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

use*_*916 2 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}))
Run Code Online (Sandbox Code Playgroud)

在我看来,聚合函数需要知道当前组是很常见的事情.在这种情况下是否有更直接的模式?


编辑:我在下面接受的解决方案包括使用apply而不是agg在GroupBy对象上.两者之间的区别在于,分别agg为每个组和每个列apply调用函数,同时为每个组调用函数(所有列一次调用).这样做的一个微妙结果是,agg它将传递一个Series当前组和列,其name属性等于原始列名.相反,applySeries使用name等于当前组的属性传递a (这是我的问题).有趣的是,当在多个列上操作时,apply将传递一个DataFrame,其中包含name设置为组名的属性(对于DataFrames通常不存在).因此,这种模式在一次聚合多个列时也有效.

有关更多信息,请参阅pandas agg和apply函数之间的区别是什么?

Ami*_*ory 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
Run Code Online (Sandbox Code Playgroud)