PythonのPandasのマージについて

Python,イメージ

AI実装検定のご案内

Pandasのmerge()関数は、データフレーム同士をキーに基づいて結合(JOIN)するための非常に強力なツールです。

これは、SQLのINNER JOINLEFT OUTER JOINなどと同じ概念で、複数のデータソースを一元化したいときに不可欠な機能です。

この記事では、基本から実践的な使い方、注意点までを丁寧に解説します。

目次

基本構文

pd.merge(df1, df2, how='inner', on='キー列')
  • df1, df2: 結合するDataFrame
  • how: 結合の方法(下記参照)
  • 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=14は除外されます(共通していないため)。

列名が異なる場合:left_onright_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

解説

  • df1df2 の「年」と「月」の両方が一致する行のみが結合されます。
  • 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 ononを省略したが共通列がなかったon=列名を明示する
データ量が爆発キーが重複していたvalidate='one_to_one'でチェック

まとめ

機能内容
柔軟な結合複数列・異なる列名・インデックス同士でも結合可能
結合方法の選択'inner', 'left', 'outer', 'right'を柔軟に切り替え可能
エラー検出validateで意図しないデータ膨張を事前に防げる
カラム衝突回避suffixesで重複列名の解決も簡単

以上、PythonのPandasのマージについてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次