pandas groupby应用于多个列以生成新列

时间:2017-11-10 16:31:33

标签: python pandas pandas-groupby pandas-apply

我喜欢使用groupby-apply在pandas数据框架中生成一个新列。

例如,我有一个数据框:

df = pd.DataFrame({'A':[1,2,3,4],'B':['A','B','A','B'],'C':[0,0,1,1]})

并尝试通过groupby-apply生成新列“D”。

这有效:

df = df.assign(D=df.groupby('B').C.apply(lambda x: x - x.mean()))

as(我认为)它返回一个与dataframe具有相同索引的系列:

In [4]: df.groupby('B').C.apply(lambda x: x - x.mean())
Out[4]:
0   -0.5
1   -0.5
2    0.5
3    0.5
Name: C, dtype: float64

但是,如果我尝试使用多列生成新列,我无法将其直接分配给新列。所以这不起作用:

 df.assign(D=df.groupby('B').apply(lambda x: x.A - x.C.mean()))

返回

TypeError: incompatible index of inserted column with frame index

实际上,groupby-apply返回:

In [8]: df.groupby('B').apply(lambda x: x.A - x.C.mean())
Out[8]:
B
A  0    0.5
   2    2.5
B  1    1.5
   3    3.5
Name: A, dtype: float64

我能做到

df.groupby('B').apply(lambda x: x.A - x.C.mean()).reset_index(level=0,drop=True))

但似乎很冗长,我不确定这是否会按预期运作。

所以我的问题是:(i)pandas groupby-apply何时返回类似索引的系列与多索引系列? (ii)是否有更好的方法通过groupby-apply到多列来分配新列?

2 个答案:

答案 0 :(得分:2)

对于这种情况,我不认为在申请中包含A列是必要的,我们可以使用transform

df.A-df.groupby('B').C.transform('mean')
Out[272]: 
0    0.5
1    1.5
2    2.5
3    3.5
dtype: float64

您可以将其分配回来

df['diff']= df.A-df.groupby('B').C.transform('mean')
df
Out[274]: 
   A  B  C  diff
0  1  A  0   0.5
1  2  B  0   1.5
2  3  A  1   2.5
3  4  B  1   3.5

答案 1 :(得分:1)

让我们在groupby中使用group_keys=False

df.assign(D=df.groupby('B', group_keys=False).apply(lambda x: x.A - x.C.mean()))

输出:

   A  B  C    D
0  1  A  0  0.5
1  2  B  0  1.5
2  3  A  1  2.5
3  4  B  1  3.5
相关问题