pandas groupby 应用于多个列以生成新列
Posted
技术标签:
【中文标题】pandas groupby 应用于多个列以生成新列【英文标题】:pandas groupby apply on multiple columns to generate a new column 【发布时间】:2018-04-23 22:45:36 【问题描述】:我喜欢使用 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()))
因为(我认为)它返回与数据框具有相同索引的系列:
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 将新列分配给多个列?
【问题讨论】:
【参考方案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
【讨论】:
这直接回答了我的问题。 请注意,此解决方案仅在.apply()
方法返回与您分配的数据框具有相同行数的系列时才有效。否则返回的系列的索引和数据框不匹配。
@petrovski 感谢您指出这一点,我想知道这样的事情会如何工作【参考方案2】:
对于这种情况,我认为不需要在 apply 中包含 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
【讨论】:
以上是关于pandas groupby 应用于多个列以生成新列的主要内容,如果未能解决你的问题,请参考以下文章
Pandas 组合 BQ 表中的多个列以生成 FB 转换 api 的有效负载
基于pandas groupby拆分dataframe并生成多个PDF
Groupby并通过在Pandas中随机分配多个字符串来创建一个新列
pandas将初始dataframe基于分组变量拆分为多个新的dataframe使用groupby函数tuple函数dict函数(splitting dataframe multiple)