【问题标题】:how to apply functions to grouped dataframes in Python pandas?如何将函数应用于 Python pandas 中的分组数据框?
【发布时间】:2013-02-09 20:04:52
【问题描述】:

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

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

我想为每个组应用一个函数,该函数对grouped_iris 中的列子集执行特定操作。我如何为每个组应用一个函数(Name 的每个值)求和 PetalLengthPetalWidth 并将其放入一个名为 SumLengthWidth 的新列中?我知道我可以将每组的所有列与agg 相加,如下所示:

grouped_iris.agg(sum)

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

【问题讨论】:

    标签: python numpy pandas


    【解决方案1】:

    不知道您是否想要汇总数字(在这种情况下,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,将 groupby 与 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
    

    但这只会给你 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
    

    【讨论】:

    • 您能否详细解释一下grouped_iris[cols].transform(sum) 在这里究竟做了什么以及transform 通常是如何使用的?看了它的文档后,我仍然感到困惑。谢谢。
    【解决方案2】:

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

    grouped_iris[['PetalLength', 'PetalWidth']].sum().sum(axis=1)
    

    【讨论】:

      猜你喜欢
      • 2016-06-04
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      • 2018-08-27
      • 1970-01-01
      相关资源
      最近更新 更多