1. ホーム
  2. python

[解決済み] Python: pandasは複数のデータフレームをマージする

2022-03-04 17:43:59

質問

異なるデータフレームがあり、日付カラムに基づいてそれらをマージする必要があります。もし、データフレームが2つしかない場合、私は df1.merge(df2, on='date') 3つのデータフレームで行う場合は df1.merge(df2.merge(df3, on='date'), on='date') しかし、複数のデータフレームを使用すると、非常に複雑になり、読めなくなります。

すべてのデータフレームに共通するのは、1つのカラムです。 date しかし、それらは同じ数の行や列を持っておらず、私は各日付がすべてのデータフレームに共通であるそれらの行だけが必要です。

そこで、すべてのデータを含むdataframeを返す再帰関数を書こうとしているのですが、うまくいきませんでした。では、どのように複数のデータフレームをマージすればいいのでしょうか?

様々な方法を試しましたが、次のようなエラーが出ました。 out of range , keyerror 0/1/2/3can not merge DataFrame with instance of type <class 'NoneType'> .

これが、私が書いたスクリプトです。

dfs = [df1, df2, df3] # list of dataframes

def mergefiles(dfs, countfiles, i=0):
    if i == (countfiles - 2): # it gets to the second to last and merges it with the last
        return

    dfm = dfs[i].merge(mergefiles(dfs[i+1], countfiles, i=i+1), on='date')
    return dfm

print(mergefiles(dfs, len(dfs)))

一例です。 df_1:

May 19, 2017;1,200.00;0.1%
May 18, 2017;1,100.00;0.1%
May 17, 2017;1,000.00;0.1%
May 15, 2017;1,901.00;0.1%

df_2です。

May 20, 2017;2,200.00;1000000;0.2%
May 18, 2017;2,100.00;1590000;0.2%
May 16, 2017;2,000.00;1230000;0.2%
May 15, 2017;2,902.00;1000000;0.2%

df_3です。

May 21, 2017;3,200.00;2000000;0.3%
May 17, 2017;3,100.00;2590000;0.3%
May 16, 2017;3,000.00;2230000;0.3%
May 15, 2017;3,903.00;2000000;0.3%

期待されるマージ結果。

May 15, 2017;  1,901.00;0.1%;  2,902.00;1000000;0.2%;   3,903.00;2000000;0.3%   

解決方法は?

以下は、複雑なクエリを使用しない場合、複数のデータフレームをマージする最もクリーンで理解しやすい方法です。

単純に 日付 をインデックスとして使用し、マージは OUTER メソッドを使用します(すべてのデータを取得するため)。

import pandas as pd
from functools import reduce

df1 = pd.read_table('file1.csv', sep=',')
df2 = pd.read_table('file2.csv', sep=',')
df3 = pd.read_table('file3.csv', sep=',')

さて、基本的にはデータフレームとして持っているすべてのファイルをリストに読み込みます。そして、ファイルをマージするには merge または reduce 関数を使用します。

# compile the list of dataframes you want to merge
data_frames = [df1, df2, df3]

注:上記のリストの中にいくつでもデータフレームを追加することができます。 これがこの方法の良いところです。複雑なクエリーは必要ありません。

同じ日付に属する値を保持するために、それを DATE

df_merged = reduce(lambda  left,right: pd.merge(left,right,on=['DATE'],
                                            how='outer'), data_frames)

# if you want to fill the values that don't exist in the lines of merged dataframe simply fill with required strings as

df_merged = reduce(lambda  left,right: pd.merge(left,right,on=['DATE'],
                                            how='outer'), data_frames).fillna('void')

  • これで、同じ日付の値が同じ行に出力されるようになりました。
  • fillna()を使用すると、異なるフレームから異なる列の非存在データを充填することができます。

その後、必要に応じてマージされたデータをcsvファイルに書き出します。

pd.DataFrame.to_csv(df_merged, 'merged.txt', sep=',', na_rep='.', index=False)

これは、次のようになります。

DATE VALUE1 VALUE2 VALUE3 ....