如何在Python pandas中对分组数据框应用函数?
我正在按照数据框中的一列对数据进行分组,下面是一个使用 iris
数据集的例子:
grouped_iris = iris.groupby(by="Name")
我想对每个组应用一个函数,这个函数会对 grouped_iris
中某些列进行特定的操作。具体来说,我想对每个组(每个 Name
的值)计算 PetalLength
和 PetalWidth
的总和,并把结果放在一个叫做 SumLengthWidth
的新列里。我知道我可以用 agg
来对每个组的所有列进行求和,像这样:
grouped_iris.agg(sum)
但我想要的是一个变体:我不想对每个 Name
的所有列求和,而是只对某些特定的列(SepalWidth, SepalLength
)进行求和。谢谢。
2 个回答
2
这看起来有点不太优雅,但能完成任务:
grouped_iris[['PetalLength', 'PetalWidth']].sum().sum(axis=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
来进行分组汇总会给你每个组的总和。
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
但这样只会给你两个数字;每个组一个。在一般情况下,如果你想把这两个数字映射回 原始 数据框,你需要使用 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