pd.merge:内部結合と外部結合
共通のキー列を使って2つのDataFrameを内部結合または外部結合し、どの行が保持・削除されるかを理解します。
「pd.merge:内部結合と外部結合」はCoddyKit上の無料Pandas & NumPy Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPandas & NumPy Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Pandas & NumPy Academyコースには全4レッスンが含まれています。
Join とは
join は、共通のキー列に基づいて行を照合し、2 つの DataFrame を結合します。これは SQL の JOIN 句と同じ考え方です。Pandas では pd.merge() を使って join を実行します。単にデータを積み重ねる pd.concat() とは異なり、pd.merge() は、1 つ以上の列の値が一致するかどうかに基づいて、異なる 2 つのテーブルの行を適切に対応付けます。
共通のキー列
merge を実行するには、両方の DataFrame に共通する値を持つ列が少なくとも 1 つ必要です。これをキー列と呼びます。たとえば、orders テーブルに customer_id 列があり、customers テーブルにも customer_id 列があるとします。customer_id をキーにして merge すると、各注文行に顧客情報が追加されます。両方の DataFrame で列名が同じ場合は、on パラメータでキーを指定します。
import pandas as pd
orders = pd.DataFrame({
'order_id': [1, 2, 3, 4],
'customer_id': [101, 102, 101, 103],
'amount': [250, 80, 320, 150]
})
customers = pd.DataFrame({
'customer_id': [101, 102, 104],
'name': ['Alice', 'Bob', 'Diana']
})Inner Join:両テーブルの共通部分
inner join(デフォルト)は、キーの値が両方の DataFrame に存在する行だけを残します。どちらか一方のテーブルにしか存在せず、もう一方に一致するキーがない行は、何も通知されずに削除されます。orders の例では、customer 103 と 104 はもう一方のテーブルに一致する行がないため、inner join の結果から除外されます。
# Inner join (default): only matching rows from both
result = pd.merge(orders, customers, on='customer_id', how='inner')
print(result)
# order_id customer_id amount name
# 0 1 101 250 Alice
# 1 3 101 320 Alice
# 2 2 102 80 Bob
# Order 4 (customer 103) dropped - no match in customers
# Diana (customer 104) dropped - no match in ordersOuter Join:両テーブルの和集合
outer join(how='outer')は、両方の DataFrame からすべての行を残します。もう一方のテーブルに一致するキーがない行では、不足している列が NaN で埋められます。これは、片方のデータセットで一致しなかったレコードも保持し、両方のデータセットを完全に把握したい場合に便利です。
result = pd.merge(orders, customers, on='customer_id', how='outer')
print(result)
# order_id customer_id amount name
# 0 1.0 101 250.0 Alice
# 1 3.0 101 320.0 Alice
# 2 2.0 102 80.0 Bob
# 3 4.0 103 150.0 NaN <- order with unknown customer
# 4 NaN 104 NaN Diana <- customer with no orders異なる名前の列を使った Merge
各 DataFrame でキー列の名前が異なる場合は、on の代わりに left_on と right_on を使います。Pandas は、左側の DataFrame の left_on と右側の DataFrame の right_on が等しい行を照合します。結果には両方のキー列が含まれるため、不要な方は後から削除できます。
products = pd.DataFrame({
'prod_id': [10, 20, 30],
'name': ['Widget', 'Gadget', 'Doohickey']
})
order_lines = pd.DataFrame({
'item_id': [10, 10, 20],
'qty': [3, 1, 5]
})
result = pd.merge(order_lines, products,
left_on='item_id', right_on='prod_id')
print(result.drop(columns='prod_id'))
# item_id qty name
# 0 10 3 Widget
# 1 10 1 Widget
# 2 20 5 Gadget複数の列を使った Merge
列の組み合わせ(複合キー)で行を照合するには、on にリストを渡します。これは、1 つの列だけでは一意に照合できない場合によく使われます。たとえば、year と region の両方をキーにして merge できます。結果に含めるには、指定したすべての列が同時に一致する必要があります。
targets = pd.DataFrame({
'year': [2023, 2023, 2024],
'region': ['East', 'West', 'East'],
'target': [100, 150, 120]
})
actuals = pd.DataFrame({
'year': [2023, 2024, 2024],
'region': ['East', 'East', 'West'],
'actual': [95, 115, 80]
})
result = pd.merge(targets, actuals, on=['year', 'region'], how='inner')
print(result)
# year region target actual
# 0 2023 East 100 95
# 1 2024 East 120 115重複する列名の扱い
両方の DataFrame に、キー以外で同じ名前の列がある場合、Pandas は区別できるようにサフィックスを付けます。デフォルトでは、左側に _x、右側に _y が付きます。suffixes パラメータでこれらを変更し、より意味のある名前にして結果の混乱を避けることができます。
df_a = pd.DataFrame({'id': [1, 2], 'value': [10, 20]})
df_b = pd.DataFrame({'id': [1, 2], 'value': [100, 200]})
# Default suffixes
print(pd.merge(df_a, df_b, on='id'))
# id value_x value_y
# Custom suffixes
print(pd.merge(df_a, df_b, on='id', suffixes=('_budget', '_actual')))
# id value_budget value_actual予期しない重複の確認
merge でよくある問題は、予期しない行の増加です。両方の DataFrame のキー列に重複値があると、merge によって一致するすべての行の直積が生成されます。merge 後は必ず行数を確認してください。想定より多い場合は、df.duplicated(subset=['key']).sum() を使ってキー列の重複を調べます。
# Both tables have duplicate keys -> cartesian product
left = pd.DataFrame({'id': [1, 1], 'val_l': ['a', 'b']})
right = pd.DataFrame({'id': [1, 1], 'val_r': ['x', 'y']})
result = pd.merge(left, right, on='id')
print(len(result)) # 4 rows! (2x2 cartesian product)
print(result)
# id val_l val_r
# 0 1 a x
# 1 1 a y
# 2 1 b x
# 3 1 b y安全性を高める validate パラメータ
validate パラメータを渡すと、merge における関係の制約を適用し、制約に違反した場合にエラーを発生させられます。'one_to_one' は両方のテーブルでキーが一意であることを要求し、'one_to_many' は左側のテーブルだけでキーが一意であることを要求し、'many_to_one' は右側のテーブルだけでキーが一意であることを要求します。これは、データ品質の問題を早期に検出できる優れた防御的コーディング手法です。
# Safe merge: validate that customer_id is unique in customers
try:
result = pd.merge(orders, customers,
on='customer_id',
how='inner',
validate='many_to_one')
print('Merge OK, shape:', result.shape)
except Exception as e:
print('Merge error:', e)indicator による対応状況の確認
indicator=True を渡すと、各行がどこから来たかを示す _merge 列が結果に追加されます。値は 'left_only'、'right_only'、'both' のいずれかです。これは outer join の後に、一致したレコードと一致しなかったレコードを特定するのに便利です。_merge 列を削除する前に、データ品質を監査できます。
result = pd.merge(orders, customers, on='customer_id',
how='outer', indicator=True)
print(result['_merge'].value_counts())
# both 3
# left_only 1 <- orders with no customer record
# right_only 1 <- customers with no orders
# Find unmatched orders
print(result[result['_merge'] == 'left_only'])Inner と Outer のまとめ
2 種類の join をまとめると、inner join は共通部分、つまり両方の DataFrame でキーが一致する行だけを返します。outer join は和集合、つまり両方の DataFrame のすべての行を返し、一致しない部分は NaN になります。補足すると、left join は左側の DataFrame のすべての行を保持し、right join は右側の DataFrame のすべての行を保持します。これらについては次のレッスンで扱います。
# Quick reference
# how='inner' -> intersection: only matched rows
# how='outer' -> union: all rows from both, NaN for no match
# how='left' -> all left rows + matched right rows
# how='right' -> all right rows + matched left rows
# Most common: inner (default) for enrichment, left for preserving records理解度チェック
このレッスンで学んだ pd.merge の inner join と outer join の理解度を確認しましょう。
レッスンのまとめ
このレッスンでは、how='inner' を指定した pd.merge() は両方の DataFrame から一致する行だけを残し、how='outer' は一致しない部分を NaN にしてすべての行を残すこと、on は共通のキーを指定し、left_on/right_on は列名が異なる場合に使うこと、そして indicator パラメータでどの行が一致したかを確認できることを学びました。次は、一方の側のすべての行を保持する left join と right join について学びます。
よくある質問
「pd.merge:内部結合と外部結合」レッスンは無料ですか?
はい。「pd.merge:内部結合と外部結合」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Pandas & NumPy Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Pandas & NumPy Academyコースには全4レッスンが含まれています。
「pd.merge:内部結合と外部結合」で何を学びますか?
共通のキー列を使って2つのDataFrameを内部結合または外部結合し、どの行が保持・削除されるかを理解します。 ブラウザで直接実行するハンズオンコードでPandas & NumPy Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Pandas & NumPy Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのPandas & NumPy Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「pd.merge:内部結合と外部結合」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このPandas & NumPy Academyレッスンでコードを書いて実行できますか?
はい。すべてのPandas & NumPy Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- DataFrameの結合に使うpd.concat
- pd.merge:内部結合と外部結合
- 左結合と右結合
- インデックスによる結合