はじめに
データ前処理を行う際に、与えられる入力ファイルが複数に分かれている場合は
元となる情報に対して、トランザクション情報を集約・マージし一つのデータフレームとして扱うことが多々あります。
そのような問題に直面した時、以下のコードを参照してもらうと実装がスムーズに進むと思います。
※以下のコードはFabienDaniel氏による投稿を参考にしています。偉大な先駆者に感謝です。
引用元:https://www.kaggle.com/fabiendaniel/elo-world
集約処理
import numpy as np
import pandas as pd
def aggregate(df):
# 集約するカラムと集計方法を明記
agg_func = {
'a': ['sum', 'mean', 'max', 'min', 'std'],
'b': ['mean'],
'c': ['mean'],
}
agg_df = df.groupby(['id']).agg(agg_func)
agg_df.columns = ['_'.join(col).strip() for col in agg_df.columns.values]
agg_df.reset_index(inplace=True)
df = (df.groupby('id')
.size()
.reset_index(name='count'))
agg_df = pd.merge(df, agg_df, on='id', how='left')
return agg_df
解説
上記の関数はpandasのデータフレームを引数として渡し、
関数内部のagg_funcに設定したカラムと集約方法でデータフレームにカラムを追加して返却します。
以下の実行例をご覧ください。
実行例
今回は、いい感じのデータがなかったのでデータを手作りしていきます。
id_values = [1, 2, 3]
name_values = ['hiroyuki','taro','jiro']
my_dict = {"id": id_values, "name": name_values}
mst_df = pd.DataFrame.from_dict(my_dict)
mst_df
上記はいわゆるマスタデータのようなもので、
カラムはid,nameの2つしかありません。
今回はhiroyuki,taro,jiroの3人分のデータです。
次にこの3人に対するトランザクションデータを作成していきます。
id_values = [1,1,1,1,2,2,2,3,3,3]
a_values = np.random.rand(10)
b_values = np.random.rand(10)
c_values = np.random.rand(10)
my_dict = {"id": id_values, "a": a_values,"b":b_values,"c":c_values}
tran_df = pd.DataFrame.from_dict(my_dict)
tran_df
トランザクションデータはidをキーとして、a,b,cのカラムが存在します。
※a,b,cのカラムの集約値を取得していきます。
hiroyukiに対して4件、taroに3件、jiroに3件のデータを用意しました。
早速、先ほどの関数を使っていきます。
tran_df = aggregate(tran_df)
tran_df
関数内部のagg_funcに対して指定した通りの集約が行われました。
カラム名は「集約元のカラム名_集約方法」となります。
最後に必要に応じて他のデータフレームとマージします。
result = pd.merge(mst_df, tran_df, on='id', how='left')
result
以上です。
集約方法に関しては、大体今回使った以下の5つで事足りる場合がほとんどだと思います。
sum:合計値
mean:平均値
max:最大値
min:最小値
std:標準偏差
他にも使いたいという方はこちらを参照ください。
http://pandas.pydata.org/pandas-docs/stable/groupby.html