Pandasのmerge()
関数は、データフレーム同士をキーに基づいて結合(JOIN)するための非常に強力なツールです。
これは、SQLのINNER JOIN
やLEFT OUTER JOIN
などと同じ概念で、複数のデータソースを一元化したいときに不可欠な機能です。
この記事では、基本から実践的な使い方、注意点までを丁寧に解説します。
目次
基本構文
pd.merge(df1, df2, how='inner', on='キー列')
df1
,df2
: 結合するDataFramehow
: 結合の方法(下記参照)on
: 結合に使う共通の列名(省略も可能)left_on
,right_on
: 列名が異なる場合に使用left_index
,right_index
: インデックスをキーにする場合suffixes
: 重複列名の自動解決用サフィックスvalidate
: 結合前にキーの一意性を検証(重要)
how
で指定する結合方法一覧
値 | 内容 | SQL相当 |
---|---|---|
'inner' | 両DataFrameに共通して存在するキーの行だけを結合(デフォルト) | INNER JOIN |
'left' | 左側のすべてのキーを保持、右側は一致するデータのみ | LEFT OUTER JOIN |
'right' | 右側のすべてのキーを保持、左側は一致するデータのみ | RIGHT OUTER JOIN |
'outer' | 両方のキーをすべて保持。どちらか一方に存在しない行はNaNが補完される | FULL OUTER JOIN |
基本例:共通キーによるINNER JOIN
import pandas as pd
df1 = pd.DataFrame({
'社員ID': [1, 2, 3],
'名前': ['田中', '鈴木', '佐藤']
})
df2 = pd.DataFrame({
'社員ID': [2, 3, 4],
'部署': ['営業', '開発', '総務']
})
pd.merge(df1, df2, on='社員ID', how='inner')
出力結果
社員ID 名前 部署
0 2 鈴木 営業
1 3 佐藤 開発
※ 社員ID=1
と4
は除外されます(共通していないため)。
列名が異なる場合:left_on
とright_on
異なる名前の列を結合キーにしたい場合に使用します。
on=
は使えないため、left_on=
と right_on=
をセットで使います。
import pandas as pd
df1 = pd.DataFrame({
'社員番号': [101, 102, 103],
'名前': ['田中', '鈴木', '佐藤']
})
df2 = pd.DataFrame({
'ID': [102, 103, 104],
'部署': ['営業', '開発', '総務']
})
result = pd.merge(df1, df2, left_on='社員番号', right_on='ID', how='inner')
print(result)
出力結果
社員番号 名前 ID 部署
0 102 鈴木 102 営業
1 103 佐藤 103 開発
解説
df1
ではキーとなる列が'社員番号'
、df2
では'ID'
という別名の列です。left_on='社員番号'
とright_on='ID'
を明示することで、両DataFrameの異なる列同士を結合できます。- デフォルトの
how='inner'
により、両方のDataFrameに共通して存在するキー(この例では 102 と 103)のみが対象となります。 - 結合後は、
社員番号
とID
の両方の列が残ります(同じ値が入っています)。
インデックスを使った結合
left_index=True, right_index=True
を指定することで、列ではなくインデックスを結合キーとして使用できます。これは、行の意味に応じたマッチングが必要な場面で非常に有効です。
import pandas as pd
# df1: インデックスを使った名前リスト
df1 = pd.DataFrame({
'名前': ['田中', '鈴木', '佐藤']
}, index=[1001, 1002, 1003])
# df2: インデックスを使った部署リスト
df2 = pd.DataFrame({
'部署': ['営業', '開発', '総務']
}, index=[1002, 1003, 1004])
# インデックスをキーにして結合
result = pd.merge(df1, df2, left_index=True, right_index=True, how='inner')
print(result)
出力結果
名前 部署
1002 鈴木 営業
1003 佐藤 開発
解説
df1
のインデックスは 1001〜1003、df2
は 1002〜1004。how='inner'
により、両方のインデックスに共通する 1002・1003 のみが結合対象となります。- 結果の DataFrame のインデックスもそのまま保持され、データの整合性が視覚的にわかりやすい。
複数列をキーにする
pd.merge(df1, df2, on=['年', '月'])
複数の条件を指定することで、より厳密な行結合が可能になります。
import pandas as pd
df1 = pd.DataFrame({
'年': [2023, 2023, 2024],
'月': [1, 2, 1],
'売上': [100, 150, 200]
})
df2 = pd.DataFrame({
'年': [2023, 2024, 2024],
'月': [1, 1, 2],
'店舗数': [10, 12, 14]
})
result = pd.merge(df1, df2, on=['年', '月'], how='inner')
print(result)
出力結果
年 月 売上 店舗数
0 2023 1 100 10
1 2024 1 200 12
解説
df1
とdf2
の「年」と「月」の両方が一致する行のみが結合されます。2023年1月
と2024年1月
のデータが両方に存在していたため、その2行が出力されています。- 片方の DataFrame にしか存在しない組み合わせ(例:
2023年2月
や2024年2月
)は除外されます(INNER JOINのため)。
このように複数列をキーにして結合することで、年月や地域+店舗などの複合条件に基づいた精密なデータ統合が実現できます。
月次データや地域別分析など、実務でよく使われるパターンです。
警告:キーの重複によるデカルト積
キーに重複があると、全ての組み合わせが生成される「N×Mの膨張現象(カーティジアン積)」が発生します。
df1 = pd.DataFrame({'キー': [1, 1], 'A': ['X', 'Y']})
df2 = pd.DataFrame({'キー': [1, 1], 'B': ['P', 'Q']})
pd.merge(df1, df2, on='キー')
出力結果
キー A B
0 1 X P
1 1 X Q
2 1 Y P
3 1 Y Q
→ 意図しない膨張を防ぐにはvalidate
を使用しましょう。
pd.merge(df1, df2, on='キー', validate='one_to_one') # エラーで警告
\
列名の重複とsuffixes
同名の列がキー以外にも存在する場合、自動で _x
, _y
が付与されます。
df1 = pd.DataFrame({'社員ID': [1], '名前': ['田中']})
df2 = pd.DataFrame({'社員ID': [1], '名前': ['Tanaka']})
pd.merge(df1, df2, on='社員ID')
出力結果
社員ID 名前_x 名前_y
0 1 田中 Tanaka
サフィックスを任意に変更可能
pd.merge(df1, df2, on='社員ID', suffixes=('_jp', '_en'))
merge()
とjoin()
とconcat()
の違い
関数 | 主な用途 | 結合対象 | 備考 |
---|---|---|---|
merge() | SQL的なキーによる結合 | 任意の列/インデックス | 最も柔軟で汎用的 |
join() | インデックス同士の結合に最適 | インデックス | df1.join(df2) の形で使う |
concat() | 縦または横の単純な結合 | 軸方向(axis) | インデックス整合が必要な場面多い |
よくあるエラーと対処法
エラー内容 | 原因 | 対処法 |
---|---|---|
ValueError: columns overlap but no suffix specified | 同名列があり、明示的にsuffixes を指定していない | suffixes=('_x', '_y') を明示 |
MergeError: No common columns to perform merge on | on を省略したが共通列がなかった | on=列名 を明示する |
データ量が爆発 | キーが重複していた | validate='one_to_one' でチェック |
まとめ
機能 | 内容 |
---|---|
柔軟な結合 | 複数列・異なる列名・インデックス同士でも結合可能 |
結合方法の選択 | 'inner' , 'left' , 'outer' , 'right' を柔軟に切り替え可能 |
エラー検出 | validate で意図しないデータ膨張を事前に防げる |
カラム衝突回避 | suffixes で重複列名の解決も簡単 |
以上、PythonのPandasのマージについてでした。
最後までお読みいただき、ありがとうございました。