我按照以下列之一对我的数据框进行分组,如下所示(使用iris
数据集的示例):
grouped_iris = iris.groupby(by="Name")
我想为每个组应用一个函数,该函数使用grouped_iris
中的列的子集执行特定操作。我如何应用针对每个组的功能(Name
的每个值)总和PetalLength
和PetalWidth
并将其放入名为SumLengthWidth
的新列中?我知道我可以将每个组的所有列与agg
相加,如下所示:
grouped_iris.agg(sum)
但我正在寻找的是对此的一种扭曲:我不想对每列的特定Name
的所有条目求和,而是只想对列的一部分求和(SepalWidth, SepalLength
)对于每个Name
组。感谢。
答案 0 :(得分:2)
这似乎有些不优雅,但是做的工作是:
grouped_iris[['PetalLength', 'PetalWidth']].sum().sum(axis=1)
答案 1 :(得分:2)
无法判断您是否需要汇总数字(在这种情况下,Andy的解决方案是您想要的),或者您是否希望将其转换回原始数据帧。如果是后者,您可以使用transform
In [33]: cols = ['PetalLength', 'PetalWidth']
In [34]: transformed = grouped_iris[cols].transform(sum).sum(axis=1)
In [35]: iris['SumLengthWidth'] = transformed
In [36]: iris.head()
Out[36]:
SepalLength SepalWidth PetalLength PetalWidth Name SumLengthWidth
0 5.1 3.5 1.4 0.2 Iris-setosa 85.4
1 4.9 3.0 1.4 0.2 Iris-setosa 85.4
2 4.7 3.2 1.3 0.2 Iris-setosa 85.4
3 4.6 3.1 1.5 0.2 Iris-setosa 85.4
4 5.0 3.6 1.4 0.2 Iris-setosa 85.4
修改:一般情况示例
通常,对于数据框df
,使用sum
聚合groupby会为您提供每个组的总和
In [47]: df
Out[47]:
Name val1 val2
0 foo 6 3
1 bar 17 4
2 foo 16 6
3 bar 7 3
4 foo 6 13
5 bar 7 1
In [48]: grouped = df.groupby('Name')
In [49]: grouped.agg(sum)
Out[49]:
val1 val2
Name
bar 31 8
foo 28 22
在您的情况下,您有兴趣对这些行进行求和:
In [50]: grouped.agg(sum).sum(axis=1)
Out[50]:
Name
bar 39
foo 50
但那只能给你2个数字;每组1个。通常,如果您希望将这两个数字投射回原始数据框,则需要使用transform
:
In [51]: grouped.transform(sum)
Out[51]:
val1 val2
0 28 22
1 31 8
2 28 22
3 31 8
4 28 22
5 31 8
请注意这些值与agg
,但生成的值完全相同,即它与原始df
具有相同的尺寸。另请注意每个其他值是如何重复的,因为行[0,2,4]和[1,3,5]是相同的组。在您的情况下,您需要两个值的总和,因此您可以在行之间对此进行求和。
In [52]: grouped.transform(sum).sum(axis=1)
Out[52]:
0 50
1 39
2 50
3 39
4 50
5 39
您现在有一个与原始数据帧长度相同的系列,因此您可以将其作为列分配回来(或者用它做你喜欢的事情):
In [53]: df['val1 + val2 by Name'] = grouped.transform(sum).sum(axis=1)
In [54]: df
Out[54]:
Name val1 val2 val1 + val2 by Name
0 foo 6 3 50
1 bar 17 4 39
2 foo 16 6 50
3 bar 7 3 39
4 foo 6 13 50
5 bar 7 1 39