3

我按以下列之一对我的数据框进行分组(以iris数据集为例):

grouped_iris = iris.groupby(by="Name")

我想为每个组应用一个函数,该函数对grouped_iris. 我如何应用一个函数来为每个组(每个值Name)求和PetalLength并将PetalWidth其放入一个名为 的新列中SumLengthWidth?我知道我可以这样总结每组的所有列agg

grouped_iris.agg(sum)

但我正在寻找的是对此的一个转折:Name我不想对每一列的特定条目的所有条目求和,而是只想SepalWidth, SepalLength对每个Name组的列的一个子集 ( ) 求和。谢谢。

4

2 回答 2

2

这似乎有点不雅,但确实有效:

grouped_iris[['PetalLength', 'PetalWidth']].sum().sum(axis=1)
于 2013-02-24T17:46:46.293 回答
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

编辑:一般案例示例

一般来说,对于一个 dataframe df,聚合 groupbysum给你每个组的总和

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
于 2013-02-24T17:55:52.340 回答