pandas の concat で複数のデータフレームを縦・横に連結する

pandas でデータフレームを結合する方法には mergeconcat があります。merge が列の値をキーにした横方向の結合であるのに対し、concat は単純にデータフレームを縦や横に連結します。

縦方向の連結

複数のデータフレームを縦に積み重ねるには、concat にリストで渡します。

import pandas as pd

df1 = pd.DataFrame({
    'name': ['Alice', 'Bob'],
    'score': [80, 90]
})

df2 = pd.DataFrame({
    'name': ['Charlie', 'Dave'],
    'score': [70, 85]
})

result = pd.concat([df1, df2])
print(result)

このコードを実行すると、df1 の下に df2 が連結された 4 行のデータフレームができます。デフォルトでは元のインデックスがそのまま保持されるため、インデックスが重複することがあります。

インデックスをリセットする

連結後にインデックスを振り直したい場合は、ignore_index=True を指定します。

result = pd.concat([df1, df2], ignore_index=True)

これで 0, 1, 2, 3 という連番のインデックスになります。大量のデータを連結するときは、この設定をしておくのが無難です。

横方向の連結

axis=1 を指定すると、横方向に連結できます。

df1 = pd.DataFrame({
    'name': ['Alice', 'Bob'],
    'age': [25, 30]
})

df2 = pd.DataFrame({
    'score': [80, 90],
    'grade': ['A', 'A']
})

result = pd.concat([df1, df2], axis=1)

この場合、インデックスが一致する行同士が横に並びます。インデックスが異なると NaN が入るので注意してください。

列が異なる場合の挙動

縦に連結するとき、列が完全に一致していなくても連結できます。

df1 = pd.DataFrame({
    'name': ['Alice'],
    'score': [80]
})

df2 = pd.DataFrame({
    'name': ['Bob'],
    'grade': ['A']
})

result = pd.concat([df1, df2])

存在しない列は NaN で埋められます。共通の列だけを残したい場合は join='inner' を指定します。

result = pd.concat([df1, df2], join='inner')

3 つ以上のデータフレームを連結する

concat はリストを受け取るので、3 つ以上でも同じように連結できます。

df_list = [df1, df2, df3, df4]
result = pd.concat(df_list, ignore_index=True)

ループで作成した複数のデータフレームをまとめるときに便利です。

merge との使い分け

concat

単純に縦・横に連結する。キーによるマッチングは行わない。同じ形式のデータを積み重ねるときに使う。

merge

列の値をキーにして結合する。SQL の JOIN と同じ。関連するテーブルを結合するときに使う。

月ごとのデータをまとめるなら concat、マスターデータを紐づけるなら merge という使い分けが一般的です。