web-dev-qa-db-ja.com

pandas groupby()with custom Aggregate function and put result in a new column

3列のデータフレームがあるとします。列の1つでグループ化し、カスタム集計関数を使用して各グループの新しい値を計算したいと思います。

この新しい値の意味はまったく異なり、その列は元のデータフレームには存在しません。したがって、実際には、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)を生成します。

4
Ivan Velichko

単一の列を操作していないため、ここでは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
6
rahlf23