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)
を生成します。
単一の列を操作していないため、ここでは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