如何在Python pandas中将函数应用于分组的数据框?

3

我将我的数据框按照其中一列进行分组,如下所示(以 iris 数据集为例):

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

我想对每个分组应用一个函数,该函数会对grouped_iris中的一部分列进行特定操作。如何应用一个函数,使得对于每个组(每个Name的值),它可以对PetalLengthPetalWidth求和,并将结果放入一个名为SumLengthWidth的新列中?我知道我可以使用agg对每个组的所有列进行求和,就像这样:

grouped_iris.agg(sum)

但我想要的是对此的一种变化:不是为每个列求出特定Name的所有条目的总和,而是仅为每个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 聚合 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个数字,每组一个。一般来说,如果您想将这两个数字投影回原始数据框中,您需要使用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

你能否更详细地解释一下 grouped_iris[cols].transform(sum) 在这里具体做了什么,以及 transform 通常如何使用?我在查看文档后仍然感到困惑。谢谢。 - user248237

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接