【问题标题】:Pandas GroupBy.apply method duplicates first groupPandas GroupBy.apply 方法复制第一组
【发布时间】:2014-02-18 19:59:46
【问题描述】:

我的第一个 SO 问题: 我对熊猫(0.12.0-4)中 groupby 的应用方法的这种行为感到困惑,它似乎将函数 TWICE 应用于数据帧的第一行。例如:

>>> from pandas import Series, DataFrame
>>> import pandas as pd
>>> df = pd.DataFrame({'class': ['A', 'B', 'C'], 'count':[1,0,2]})
>>> print(df)
   class  count  
0     A      1  
1     B      0    
2     C      2

我先检查一下groupby功能是否正常,好像没问题:

>>> for group in df.groupby('class', group_keys = True):
>>>     print(group)
('A',   class  count
0     A      1)
('B',   class  count
1     B      0)
('C',   class  count
2     C      2)

然后我尝试在 groupby 对象上使用 apply 做类似的事情,我得到了第一行输出两次:

>>> def checkit(group):
>>>     print(group)
>>> df.groupby('class', group_keys = True).apply(checkit)
  class  count
0     A      1
  class  count
0     A      1
  class  count
1     B      0
  class  count
2     C      2

任何帮助将不胜感激!谢谢。

编辑:@Jeff 在下面提供了答案。本人密密麻麻一下子没看懂,所以这里举个简单的例子来说明,尽管上例中第一组的双打印输出,但是apply方法只对第一组操作一次,不会对原始数据帧进行变异:

>>> def addone(group):
>>>     group['count'] += 1
>>>     return group

>>> df.groupby('class', group_keys = True).apply(addone)
>>> print(df)

      class  count
0     A      1
1     B      0
2     C      2

但是通过将方法的返回分配给一个新对象,我们看到它按预期工作:

>>> df2 = df.groupby('class', group_keys = True).apply(addone)
>>> print(df2)

      class  count
0     A      2
1     B      1
2     C      3

【问题讨论】:

  • 从 v0.25 开始,行为将发生变化,因此第一组只评估一次。 Please see here.
  • 请将接受的答案更新为此answer,因为旧答案不再有效。

标签: python pandas group-by pandas-groupby


【解决方案1】:

这是设计使然,如 here here 所述

apply 函数需要知道返回数据的形状,才能智能地确定如何组合。为此,它会调用该函数(在您的情况下为 checkit)两次以实现此目的。

根据您的实际用例,您可以将调用apply 替换为aggregatetransformfilter,详细描述here。这些函数要求返回值是特定的形状,因此不要调用该函数两次。

但是 - 如果您调用的函数没有副作用,那么函数在第一个值上被调用两次很可能并不重要。

【讨论】:

    【解决方案2】:

    您可以使用 for 循环来避免 groupby.apply 重复第一行,

    log_sample.csv

    guestid,keyword
    1,null
    2,null
    2,null
    3,null
    3,null
    3,null
    4,null
    4,null
    4,null
    4,null
    

    我的代码片段

    df=pd.read_csv("log_sample.csv") 
    grouped = df.groupby("guestid")
    
    for guestid, df_group in grouped:
        print(list(df_group['guestid'])) 
    
    df.head(100)
    

    输出

    [1]
    [2, 2]
    [3, 3, 3]
    [4, 4, 4, 4]
    

    【讨论】:

      【解决方案3】:

      这个“问题”现已修复:升级到 0.25+

      从 v0.25 开始,GroupBy.apply() 只会评估第一组一次。见GH24748

      What’s new in 0.25.0 (July 18, 2019): Groupby.apply on DataFrame evaluates first group only once

      文档中的相关示例:

      pd.__version__                                                                                                          
      # '0.25.0.dev0+590.g44d5498d8'
      
      df = pd.DataFrame({"a": ["x", "y"], "b": [1, 2]})                                                                      
      
      def func(group): 
          print(group.name) 
          return group                                                                                                                     
      

      新行为 (>=v0.25):

      df.groupby('a').apply(func)                                                                                            
      x
      y
      
         a  b
      0  x  1
      1  y  2
      

      旧行为(

      df.groupby('a').apply(func)
      x
      x
      y
      
         a  b
      0  x  1
      1  y  2
      

      Pandas 仍然使用第一组来判断apply 是否可以走快速路径。但至少它不再需要对第一组进行两次评估。干得好,开发者!

      【讨论】:

      • 哦,所以基本上 Pandas 仍然会在第一行运行 apply 两次。此修复仅适用于 groupby.apply 中的组。该死的。
      • @CMCDragonkai 现在.apply也是如此。
      • 哪个版本的熊猫?
      猜你喜欢
      • 2020-04-01
      • 1970-01-01
      • 2012-09-28
      • 2019-08-17
      • 2015-08-18
      • 2018-05-29
      • 1970-01-01
      • 2018-02-23
      相关资源
      最近更新 更多