パンダで一連のデータフレームをマージしようとしています。私はdfsdfs
のリストとそれに対応するラベルのリストを持っていますlabels
.dfからの共通ラベルがリスト内のラベルからサフィックスを取得するように、すべてのdfsを1つのdfにマージしたいと考えていlabels
ます。すなわち:
def mymerge(dfs, labels):
labels_dict = dict([(d, l) for d, l in zip(dfs, labels)])
merged_df = reduce(lambda x, y:
pandas.merge(x, y,
suffixes=[labels_dict[x], labels_dict[y]]),
dfs)
return merged_df
これを試すと、次のエラーが表示されます。
pandas.tools.merge.MergeError: Combinatorial explosion! (boom)
各マージで最大でも列数 N だけ増加する一連のマージを作成しようとしています。ここで、N はリスト内の「次の」df の列数です。最終的な DF には、すべての df 列を合計した数の列が含まれている必要があるため、組み合わせではなく、加算的に成長します。
私が探している動作は次のとおりです。指定された(たとえば、によって指定されたon=
)またはdfsがインデックス付けされた列名でdfsに参加します。一般的でない列名を結合します (外部結合のように)。列が複数の dfs に表示される場合は、必要に応じて上書きします。ドキュメントをさらに見ると、update
これを行うための最良の方法のように思えます。試しjoin='outer'
てみると、実装されていないことを示す例外が発生します。
編集:
これは、サフィックスを処理しませんが、探しているマージの種類を示しています。
def my_merge(dfs_list, on):
""" list of dfs, columns to merge on. """
my_df = dfs_list[0]
for right_df in dfs_list[1:]:
# Only put the columns from the right df
# that are not in the existing combined df (i.e. new)
# or which are part of the columns to join on
new_noncommon_cols = [c for c in right_df \
if (c not in my_df.columns) or \
(c in on)]
my_df = pandas.merge(my_df,
right_df[new_noncommon_cols],
left_index=True,
right_index=True,
how="outer",
on=on)
return my_df
これは、各 dfs のインデックスでマージが行われることを前提としています。新しい列は外部結合スタイルで追加されますが、共通の (インデックスの一部ではない) 列は、on=
キーワードを介して結合で使用されます。
例:
df1 = pandas.DataFrame([{"employee": "bob",
"gender": "male",
"bob_id1": "a"},
{"employee": "john",
"gender": "male",
"john_id1": "x"}])
df1 = df1.set_index("employee")
df2 = pandas.DataFrame([{"employee": "mary",
"gender": "female",
"mary_id1": "c"},
{"employee": "bob",
"gender": "male",
"bob_id2": "b"}])
df2 = df2.set_index("employee")
df3 = pandas.DataFrame([{"employee": "mary",
"gender": "female",
"mary_id2": "d"}])
df3 = df3.set_index("employee")
merged = my_merge([df1, df2, df3], on=["gender"])
print "MERGED: "
print merged
これのひねりは、一般的な列の一連のラベルに基づいて各 df にサフィックスを任意にタグ付けすることですが、それはそれほど重要ではありません。上記のマージ操作は、パンダでよりエレガントに実行できるものですか、それとも組み込みとして既に存在するものですか?