大熊猫拆分应用合并,结果返回到原始DataFrame

时间:2018-12-16 22:14:23

标签: pandas pandas-groupby

我想在这里记录'split-apply-combine'方法的特殊情况。

问题:我从DataFrame开始,我必须对需要进行groupby拆分的数据进行一些处理并返回一些结果。让我们进一步假设处理不能通过简单的内置操作(有快捷方式)来完成,但是它非常复杂,我必须遍历各个组。此外,我希望将结果放回原始DataFrame中。 (是的,我知道,如果结果是整个组的单个标量,那么我将消耗大量内存。但是,通常我确实希望将那些结果存储在原始数据表中,而不是处理这些结果。另一张桌子)。

我发现在熊猫文档中和此处都没有很好地记录这种情况。

让我们举例说明:

import pandas as pd
import numpy as np

# Prepare DataFrame
data = {'Group':['A']*4+['B']*4+['C']*4,'Prop1':['S1','S2','S3','S4','S5','S6','S7','S8','S9','S10',
'S11','S12'],'Prop2':[2004,2004,3004,3004,4004,4004,5004,5004,6004,6004,7004,7004],
'Res1':[0,1,2,3,10,11,12,13,20,21,22,23]}
df = pd.DataFrame(data=data)
df

Initial DataFrane

现在,我们继续进行groupby运算并计算新结果:

df['Res2'] = np.nan
df['Res3'] = np.nan
grouped = df.groupby('Group')
for (key,gr) in grouped:
    # Calculate two new results based on gr values
    res2 = gr['Res1'].mean()
    gr['Res2'] = res2
    res3 = gr['Prop2'] + gr['Res1']
    gr['Res3'] = res3
    # At this point gr has two new columns Res2 and Res3
    # Now we need to copy those changes back to the original DataFrame df
    df.update(gr)

这里最棘手的部分是将结果放回到df中。请注意,我必须首先在df中创建两个新列,否则将无法正常工作。第一种方法是使用.update命令。这很容易阅读。使用%timeit命令,我将此时间定为(1.85ms,1.84ms,1.74ms)。

执行此操作的第二种方法是注意原始索引保留在gr中。因此我们可以将df.update(gr)替换为:

df.loc[gr.index,('Res2','Res3')] = gr[['Res2','Res3']]

在这些单元格中的任何一个之后,我们都得到了预期的结果(以及臭名昭著的SettingWithCopy警告):

final result

有趣的是,第二种方法稍快一些,计时时间为(1.66ms,1.69ms,1.73ms)。

我的问题是,有没有更简单的方法? 而且,对于具有行多索引的DataFrame该如何完成?

1 个答案:

答案 0 :(得分:1)

您可以对Res2使用变换,而Res3只是总和。无需创建两个新列

df['Res2'] = df.groupby('Group').Res1.transform('mean')
df['Res3'] = df['Prop2'] + df['Res1']

    Group   Prop1   Prop2   Res1    Res2    Res3
0   A   S1  2004    0   1.5     2004
1   A   S2  2004    1   1.5     2005
2   A   S3  3004    2   1.5     3006
3   A   S4  3004    3   1.5     3007
4   B   S5  4004    10  11.5    4014
5   B   S6  4004    11  11.5    4015
6   B   S7  5004    12  11.5    5016
7   B   S8  5004    13  11.5    5017
8   C   S9  6004    20  21.5    6024
9   C   S10 6004    21  21.5    6025
10  C   S11 7004    22  21.5    7026
11  C   S12 7004    23  21.5    7027