この記事では、再帰関数とPandasのを用いることで、複数のDataFrameに対して特定列のみを取り出す方法を紹介しています。
▲図に表すとこんな感じです。
上図では結合したいDataFrameが3つしかありませんが、いくつもある場合を想定しています。
結合したい各DataFrame(df1,df2,df3,…)は、
- sample_202106.csv
- sample_202107.csv
- sample_202108.csv
- ︙
のCSVファイルから作るものとします。
例えば、sample_202106.csvの中身は以下のようになります。
会社,件数 A社,20 B社,30 C社,20
‘会社’列は固定して、各データフレームから’件数‘列のみを取り出して結合します。
その際、件数のカラム名を、ファイル名の年月の部分’202106‘に変更します。
各dfの’件数’列には、A社~E社のデータが全てあるとは限りません。
‘会社’列を固定する場合、Pandasのmergeのパラメータ「on」を使えば良いので、mergeを使って書いてみます。
まずdf1とdf2だけをmergeで結合する場合について考えてみます。
pd.merge(df1, df2, on='会社',how='outer')
で結合できます。
ただし、df1,df2は、
df1 = pd.read_csv('sample_202106.csv') df1 = df1.columns = ['会社', 202106] df2 = pd.read_csv('sample_202107.csv') df2 = df2.columns = ['会社', 202107]
です。
▲pd.merge(df1, df2, on=’会社’,how=’outer’)の出力結果
続いて、(df1とdf2を結合したデータフレーム)とdf3をmergeで結合する場合について考えてみます。すると、
pd.merge(df12, df3, on='会社',how='outer')
と表現できます。ただし、
df12=pd.merge(df1, df2, on='会社',how='outer')
です。
▲pd.merge(df12, df3, on=’会社’,how=’outer’)の出力結果
これを続けていけば、任意の数のdfをmergeによってすべて結合することができそうです。
df12を代入した場合、
pd.merge(pd.merge(df1, df2, on='会社',how='outer'), df3, on='会社',how='outer')
となります。一応このデータフレームに対して、さらにdf4をmergeすることを考えてみます。すると、
pd.merge(pd.merge(pd.merge(df1, df2, on='会社',how='outer'), df3, on='会社',how='outer'), df4, on='会社',how='outer')
となります。n個のデータフレームを結合したい場合について考えてみると、この形なら再帰関数を使えば実現できそうです。
その前に、ここでdf1,df2,…を作成するための関数 make_df を定義します。
def make_df(ym_list): df = pd.read_csv('sample_' + ym_list + '.csv') df.columns = ['会社', ym_list] return df
- make_df(‘202106’)とすると、df1
- make_df(‘202107’)とすると、df2
- make_df(‘202108’)とすると、df3
- ︙
が返ってくるような関数です。
さて、make_dfを定義したところで、n個のデータフレームを結合する関数 merge_df(n)について考えてみます。
まずはn=3で考えてみます。つまり、df1・df2・df3の3つを結合する場合について考えます。
ym_list=['202106', '202107', '202108']
とすると、merge_df(3)は以下のように考えることができます。merge_df(2)を使えることを意識すると、
と表現できます。つまり、
です。コードで表現すると、
merge_df(3)=pd.merge(merge_df(2), make_df(ym_list[2], on='会社', how='outer')
のようになります。
merge_df(2)の部分について考えます。merge_df(1)を使えることを意識すると、
と表現できます。
merge_df(1)は1つのデータフレームを結合することになるので、df1を出力させておけば良さそうです。
つまり、merge_df(n)において、n=1のときにはmake_df(ym_list[0])とします。
よって、
は以下のように書き換えられます。
結局、merge_df(3)は、df1・df2・df3を結合したデータフレームを作成する関数であることが確認できました。
▲merge_df(n)についての関数を定義する際のイメージ図です。
これまでの事を踏まえて、再帰関数とPandasのmergeを使って 3つ以上のDataFrameを結合する全体のコードは以下のようになります。
ym_list = ['202106', '202107', '202108'] def make_df(ym_list): df = pd.read_csv('sample_' + ym_list + '.csv') df.columns = ['会社', ym_list] return df def merge_df(n: int): #結合するデータフレームの個数をnとする if n < 1: return 0 elif n == 1: return make_df(ym_list[0]) else: return pd.merge(merge_df(n-1), make_df(ym_list[n-1]) ,on='会社',how='outer') merge_df(len(ym_list))
ym_listの長さは3つなので、merge_df(len(ym_list))は3つのデータフレームが結合された出力結果になるはずです。
▲merge_df(3)の出力結果。3つのデータフレームを結合できています。
n=1のときは、初期値として、make_df(ym_list[0])を出力するようにしています。
n<1の値が出力された場合は無限ループにならないように、意図的にエラーが発生するようにしています。
再帰関数とPandasのmergeを使って3つ以上のDataFrameを結合する方法についての紹介でした。
コメント