我可能在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
答案 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
个对象,因为df
是DataFrame
。 .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
,您如何知道汇总的群组?