带有自定义聚合函数的pandas groupby()并将结果放入新列中

时间:2018-11-08 15:58:37

标签: python pandas dataframe pandas-groupby

假设我有一个包含3列的数据框。我想按列之一对其进行分组,并使用自定义聚合函数为每个组计算一个新值。

此新值的含义完全不同,并且其列仅在原始数据框中不存在。因此,实际上,我想在groupby() + agg()转换期间更改数据框的形状。原始数据框看起来像(foo, bar, baz),并具有范围索引,而结果数据框仅需要具有(qux)列和baz作为索引。

import pandas as pd

df = pd.DataFrame({'foo': [1, 2, 3], 'bar': ['a', 'b', 'c'], 'baz': [0, 0, 1]})
df.head()

#        foo    bar    baz
#   0      1      a      0
#   1      2      b      0
#   2      3      c      1    

def calc_qux(gdf, **kw):
    qux = ','.join(map(str, gdf['foo'])) + ''.join(gdf['bar'])
    return (None, None)  # but I want (None, None, qux)

df = df.groupby('baz').agg(calc_qux, axis=1)  # ['qux'] but then it fails, since 'qux' is not presented in the frame.
df.head()

#      qux
# baz       
#   0  1,2ab
#   1  3c

如果我尝试从聚合函数返回的值数量与原始数据帧中的列数不同,则上面的代码会产生错误ValueError: Shape of passed values is (2, 3), indices imply (2, 2)

1 个答案:

答案 0 :(得分:3)

您要在此处使用apply(),因为您不是在单个列上进行操作(在这种情况下,使用agg()是合适的):

import pandas as pd

df = pd.DataFrame({'foo': [1, 2, 3], 'bar': ['a', 'b', 'c'], 'baz': [0, 0, 1]})

def calc_qux(x):

    return ','.join(x['foo'].astype(str).values) + ''.join(x['bar'].values)

df.groupby('baz').apply(calc_qux).to_frame('qux')

收益:

       qux
baz       
0    1,2ab
1       3c