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のマージについてでした。
最後までお読みいただき、ありがとうございました。
