pandas.groupby.agg中可能存在错误?

时间:2014-01-11 01:26:27

标签: python pandas

我可能在pandas.groupby.agg中发现了一个错误。请尝试以下代码。看起来传递给聚合函数的内容fn()是包含密钥的数据框。根据我的理解,agg函数分别应用于每个列,只传递一列。自''年''列出现在groupby中,应从分组结果中删除。

import pandas as pd
import numpy as np

df = pd.DataFrame({'year' : [2011,2011,2012,2012,2013], '5-1' : [1.2, 2.1,2.1,11., 13.]})

def fn(x):
    print x
    #return np.mean(x) will explode
    return 0


res = df.groupby('year').agg(fn)
print res

上面给出了输出,它清楚地告诉我fn(x)的x作为具有两列(年,5-1)的DataFrame传递。

   5-1  year
0  1.2  2011
1  2.1  2011
    5-1  year
2   2.1  2012
3  11.0  2012
   5-1  year
4   13  2013
      5-1
year     
2011    0
2012    0
2013    0

2 个答案:

答案 0 :(得分:2)

要回答您的问题,如果您绝对希望将该功能应用于Series,请使用{column: aggfunc}中的.agg()语法。

那就是说,你的代码似乎工作得很好(至少在当前的主人身上)。该功能实际上并未应用于year列。


一点解释。为此,我假设您使用的是旧版本的熊猫,并且该版本有一个已经修补过的bug。为了重现我认为你正在获得的行为,让我们重新定义fn

In [32]: def fn(x):
    print("Printing x+1 : {}".format(x + 1))
    print("Printing x: {}".format(x))
    return 0

让我们重新定义df['year']

In [33]: df['year'] = ['a', 'a', 'b', 'b', 'c']

所有这些对象都在pandas/core/groupby.py中定义。 df.groupby('year')部分返回DataFrameGroupby个对象,因为dfDataFrame.agg()实际上并未定义DataFrameGroupBy,而是在其父类NDFrameGroupBy上。

由于这不是一个Cython函数,所以事情会转移到NDFrameGroupBy._aggregate_generic()。它试图执行该函数,如果失败,则回退到单独的代码部分:

    try:
        for name, data in self:
            result[name] = self._try_cast(func(data, *args, **kwargs),
                                          data)
    except Exception:
        return self._aggregate_item_by_item(func, *args, **kwargs)

如果try部分成功,则该函数将应用于整个对象(这就是print x显示两列的原因),并且结果与索引上的分组器和值一起很好地呈现在列中。

如果try部分失败,则会将内容移至_aggregate_item_by_item排除分组列

这意味着,通过将代码从return np.mean(x)更改为return 0,您实际上已更改了代码所遵循的路径。之前,当您尝试使用mean时,我认为它失败了并且又回到了_aggregate_item_by_item(这就是我重新定义df['year']fn的原因,这将失败当然)。但是当你切换到return 0时,成功了,所以跟在try部分之后。

这只是一些猜测,但我认为这就是发生的事情。

我现在正在按代码进行分组工作,这个问题已经出现(参见here)。我不认为该功能应该应用于分组列,但有时是(R做同样的事情)。如果您对此事有意见,请在那里发帖。

答案 1 :(得分:0)

如果汇总中未包含year,您如何知道汇总的群组?