在常见的使用模式中,我需要使用自定义聚合函数聚合DataFrame。 在这种特殊情况下,聚合函数需要知道当前组 为了正确执行聚合。
为每个列和调用传递给DataFrameGroupBy.aggregate()
的函数,接收具有当前组和列中元素的Series。
我发现从聚合函数中获取组名的唯一方法是将分组列添加到索引中,然后使用
x.index.get_level_values('power')[0]
。这是一个例子:
def _tail_mean_user_th(x):
power = x.index.get_level_values('power')[0]
th = th_dict[power] # this values changes with the group
return x.loc[x > th].mean() - th
mbsize_df = (bursts_sel.set_index('power', append=True).groupby('power')
.agg({'nt': _tail_mean_user_th}))
在我看来,聚合函数需要知道当前组是很常见的事情。在这种情况下是否有更简单的模式?
编辑:我在下面接受的解决方案包括在GroupBy对象上使用apply
而不是agg
。两者之间的区别在于agg
分别为每个组和每个列调用函数,而apply
为每个组调用函数(所有列一次调用)。这样做的一个微妙结果是agg
将为当前组和列传递Series
,其name
属性等于原始列名。相反,apply
会传递Series
name
属性等于当前组(这是我的问题)。有趣的是,在多列操作时,apply
会传递一个DataFrame,其中name
属性(通常不存在DataFrames)设置为组名。因此,当一次聚合多个列时,此模式也有效。
有关详细信息,请参阅What is the difference between pandas agg and apply function?
答案 0 :(得分:6)
如果您使用groupby
+ apply
,则可以通过.name
属性使用它:
df = pd.DataFrame({'a': [1, 2, 1, 2], 'b': [1, 1, 2, 2]})
def foo(g):
print('at group %s' % g.name)
return int(g.name) + g.sum()
>>> df.b.groupby(df.a).apply(foo)
at group 1
at group 2
a
1 4
2 5
Name: b, dtype: int64