我可能在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作为具有两列(year,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
要回答您的问题,如果您绝对希望将函数应用于Series
,请使用中的{column: aggfunc}
语法.agg()
。
也就是说,您的代码似乎可以正常工作(至少在当前的主机上)。该函数实际上并未应用于该year
列。
有点解释。为此,我假设您使用的是较旧版本的熊猫,并且该版本存在一个已修复的错误。为了重现我认为您得到的行为,让我们重新定义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
部分也随之而来。
这只是一些猜测,但我认为这是正在发生的事情。
我现在实际上正在按代码在组上工作,并且出现了这个问题(请参阅此处)。我认为该功能永远都不应应用于分组列,但有时是这样(R也是如此)。如果您对此事有意见,请张贴在那儿。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句