Pandas GroupBy.apply方法复制第一组

时间:2014-01-27 19:37:57

标签: python pandas group-by

我的第一个问题: 我对pandas(0.12.0-4)中groupby的apply方法的这种行为感到困惑,它似乎将函数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)       打印(DF2)

    
  
      class  count
0     A      2
1     B      1
2     C      3

3 个答案:

答案 0 :(得分:30)

这是设计的,如here here

所述

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

根据您的实际使用情况,您可以将apply,[{1}}或aggregate的来电替换为transform,详细说明here。这些函数要求返回值为特定形状,因此不要两次调用该函数。

然而 - 如果您正在调用的函数没有副作用,则很可能在第一个值上调用该函数两次并不重要。

答案 1 :(得分:1)

你可以使用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

我的代码snippit

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]

答案 2 :(得分:1)

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

从v0.25开始,GroupBy.apply()将仅对第一组进行一次评估。参见GH24748

文档中的相关示例:

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

旧行为(<= v0.24.x):

df.groupby('a').apply(func)
x
x
y

   a  b
0  x  1
1  y  2

Pandas仍使用第一组来确定apply是否可以采用快速路径。但是至少它不再需要对第一组进行两次评估。做得好,开发人员!