Pandas groupby聚合将组名传递给聚合

时间:2018-05-07 21:16:22

标签: python pandas pandas-groupby

在常见的使用模式中,我需要使用自定义聚合函数聚合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?

1 个答案:

答案 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