Pandas pd.merge() 関数
pd.merge()は Pandas ライブラリ内で列に基づいて2つの DataFrame を結合するための関数です。これは SQL の JOIN 操作に似ており、1つまたは複数の共通列に基づいて2つのデータテーブルを1つに統合できます。
これはデータ分析と処理において最もよく使われる結合方法の1つであり、リレーショナルデータの処理に特に適しており、分散した異なるテーブルの関連情報を1つにまとめることができます。
単語の意味: merge「結合、融合」という意味で、ここでは2つのデータテーブルを共通のキーに基づいて結合することを指します。
基本構文とパラメータ
pd.merge()は Pandas ライブラリのトップレベル関数であり、SQL の JOIN 操作に似た操作を実装するために使われます。
構文形式
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
パラメータ説明
- パラメータ:
left- 型: DataFrame。
- 説明: 左側の DataFrame、結合に参加する1つ目のテーブル。
- パラメータ:
right- 型: DataFrame。
- 説明: 右側の DataFrame、結合に参加する2つ目のテーブル。
- パラメータ:
on- 型: 文字列または文字列リスト。
- 説明: 結合に使用する列名(キー)。左右両方の DataFrame に同じ名前の列が存在する必要があります。指定しない場合、自動的に同じ名前の列をキーとして探します。
- パラメータ:
how- 型: 文字列('left', 'right', 'outer', 'inner')。
- 説明: 結合方法。SQL の JOIN タイプに似ています。
'inner'は内部結合(共通部分)を意味し、'outer'は外部結合(和集合)を意味し、'left'は左結合(左テーブルの全レコードを保持)を意味し、'right'は右結合(右テーブルの全レコードを保持)を意味します。デフォルトは'inner'。
- パラメータ:
left_on- 型: 文字列または文字列リスト。
- 説明: 左側の DataFrame で結合キーとして使用する列名。左右のテーブルの結合キー列名が異なる場合に使用します。
- パラメータ:
right_on- 型: 文字列または文字列リスト。
- 説明: 右側の DataFrame で結合キーとして使用する列名。左右のテーブルの結合キー列名が異なる場合に使用します。
- パラメータ:
suffixes- 型> タプル。
- 説明> 左右のテーブルに同じ名前の列(結合キーではない)がある場合に区別するための接尾辞。デフォルトは
('_x', '_y')。
関数説明
- 戻り値: 結合後の DataFrame を返します。
- 効果: 指定したキーと方法に基づいて、2つの DataFrame を横方向に1つの DataFrame に結合します。
実例
簡単なものから複雑なものまで一連の例を通して、pd.merge()の使い方を完全にマスターしましょう。
例1: 基本の使い方 - 単一列に基づく内部結合
実例
import pandas as pd
# 1. 2つの DataFrame を作成
employees = pd.DataFrame({
'emp_id': [101, 102, 103, 104],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'dept_id': [1, 2, 1, 2]
})
departments = pd.DataFrame({
'dept_id': [1, 2, 3],
'dept_name': ['Engineering', 'Sales', 'Marketing']
})
print("=== 社員テーブル (employees) ===")
print(employees)
print("\n=== 部門テーブル (departments) ===")
print(departments)
# 2. pd.merge() を使用して dept_id 列に基づいて結合(内部結合、デフォルト)
result = pd.merge(employees, departments, on='dept_id')
print("\n=== pd.merge(employees, departments, on='dept_id') 内部結合 ===")
print(result)
# 1. 2つの DataFrame を作成
employees = pd.DataFrame({
'emp_id': [101, 102, 103, 104],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'dept_id': [1, 2, 1, 2]
})
departments = pd.DataFrame({
'dept_id': [1, 2, 3],
'dept_name': ['Engineering', 'Sales', 'Marketing']
})
print("=== 社員テーブル (employees) ===")
print(employees)
print("\n=== 部門テーブル (departments) ===")
print(departments)
# 2. pd.merge() を使用して dept_id 列に基づいて結合(内部結合、デフォルト)
result = pd.merge(employees, departments, on='dept_id')
print("\n=== pd.merge(employees, departments, on='dept_id') 内部結合 ===")
print(result)
実行結果の予想:
=== 员工表 (employees) === emp_id name dept_id 0 101 Alice 1 1 102 Bob 2 2 103 Charlie 1 3 104 Diana 2 === 部门表 (departments) === dept_id dept_name 0 1 Engineering 1 2 Sales 2 3 Marketing === pd.merge(employees, departments, on='dept_id') 内连接 === emp_id name dept_id dept_name 0 101 Alice 1 Engineering 1 103 Charlie 1 Engineering 2 102 Bob 2 Sales 3 104 Diana 2 Sales
コード解説:
- 2つのテーブルは
dept_id列で結合されます。これが共通列です。 - デフォルトでは内部結合(
how='inner')が使用され、両方にあるキー値(dept_id が 1 と 2)のみが保持されるため、dept_id が 3 のマーケティング部は除外されます。 - 結合後、各社員は対応する部門名に関連付けられます。
例2: 左結合と右結合
howパラメータを使用して結合方法を制御し、どちらか一方の全レコードを保持できます。
実例
import pandas as pd
# 引き続き上記のデータを使用
employees = pd.DataFrame({
'emp_id': [101, 102, 103, 104],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'dept_id': [1, 2, 1, 2]
})
departments = pd.DataFrame({
'dept_id': [1, 2, 3],
'dept_name': ['Engineering', 'Sales', 'Marketing']
})
# 1. 左結合 - 左テーブルの全レコードを保持
print("=== 左結合 (how='left') ===")
left_result = pd.merge(employees, departments, on='dept_id', how='left')
print(left_result)
# 2. 右結合 - 右テーブルの全レコードを保持
print("\n=== 右結合 (how='right') ===")
right_result = pd.merge(employees, departments, on='dept_id', how='right')
print(right_result)
# 3. 外部結合 - 両テーブルの全レコードを保持
print("\n=== 外部結合 (how='outer') ===")
outer_result = pd.merge(employees, departments, on='dept_id', how='outer')
print(outer_result)
# 引き続き上記のデータを使用
employees = pd.DataFrame({
'emp_id': [101, 102, 103, 104],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'dept_id': [1, 2, 1, 2]
})
departments = pd.DataFrame({
'dept_id': [1, 2, 3],
'dept_name': ['Engineering', 'Sales', 'Marketing']
})
# 1. 左結合 - 左テーブルの全レコードを保持
print("=== 左結合 (how='left') ===")
left_result = pd.merge(employees, departments, on='dept_id', how='left')
print(left_result)
# 2. 右結合 - 右テーブルの全レコードを保持
print("\n=== 右結合 (how='right') ===")
right_result = pd.merge(employees, departments, on='dept_id', how='right')
print(right_result)
# 3. 外部結合 - 両テーブルの全レコードを保持
print("\n=== 外部結合 (how='outer') ===")
outer_result = pd.merge(employees, departments, on='dept_id', how='outer')
print(outer_result)
実行結果の予想:
=== 左连接 (how='left') === emp_id name dept_id dept_name 0 101 Alice 1 Engineering 1 103 Charlie 1 Engineering 2 102 Bob 2 Sales 3 104 Diana 2 Sales === 右连接 (how='right') === emp_id name dept_id dept_name 0 101 Alice 1 Engineering 1 103 Charlie 1 Engineering 2 102 Bob 2 Sales 3 104 Diana 2 Sales 4 NaN NaN 3 Marketing === 外连接 (how='outer') === emp_id name dept_id dept_name 0 101 Alice 1 Engineering 1 103 Charlie 1 Engineering 2 102 Bob 2 Sales 3 104 Diana 2 Sales 4 NaN NaN 3 Marketing
コード解説:
- 左結合は左テーブル(employees)のすべての社員レコードを保持し、右テーブルに一致する部門がない場合は
NaN。 - 右結合は右テーブル(departments)のすべての部門を保持し、その部門に所属する社員がいなくても保持されます。
- 外部結合は両テーブルのすべてのレコードを保持し、一致しないフィールドは
NaNで埋められます。
例3: 列名が異なる2つのテーブルを処理する
2つのテーブルの結合キー列名が異なる場合、left_onとright_onパラメータを使用してそれぞれ指定できます。
実例
import pandas as pd
# 1. 列名が異なる2つの DataFrame を作成
students = pd.DataFrame({
'student_id': [1, 2, 3, 4],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'class_id': [101, 102, 101, 103]
})
classes = pd.DataFrame({
'class_id': [101, 102, 103],
'class_name': ['Class A', 'Class B', 'Class C'],
'teacher': ['Mr. Smith', 'Ms. Johnson', 'Mrs. Lee']
})
print("=== 学生テーブル ===")
print(students)
print("\n=== クラステーブル ===")
print(classes)
# 2. left_on と right_on を使用して異なる列名を処理
result = pd.merge(students, classes, left_on='class_id', right_on='class_id')
print("\n=== 異なる列名の場合の結合 ===")
print(result)
# 1. 列名が異なる2つの DataFrame を作成
students = pd.DataFrame({
'student_id': [1, 2, 3, 4],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'class_id': [101, 102, 101, 103]
})
classes = pd.DataFrame({
'class_id': [101, 102, 103],
'class_name': ['Class A', 'Class B', 'Class C'],
'teacher': ['Mr. Smith', 'Ms. Johnson', 'Mrs. Lee']
})
print("=== 学生テーブル ===")
print(students)
print("\n=== クラステーブル ===")
print(classes)
# 2. left_on と right_on を使用して異なる列名を処理
result = pd.merge(students, classes, left_on='class_id', right_on='class_id')
print("\n=== 異なる列名の場合の結合 ===")
print(result)
実行結果の予想:
=== 学生表 ===
student_id name class_id
0 1 Alice 101
1 2 Bob 102
2 3 Charlie 101
3 4 Diana 103
=== 班级表 ===
class_id class_name teacher
0 101 Class A Mr. Smith
1 102 Class B Ms. Johnson
2 103 Class C Mrs. Lee
=== 不同列名时的合并 ===
student_id name class_id class_name teacher
0 1 Alice 101 Class A Mr. Smith
1 3 Charlie 101 Class A Mr. Smith
2 2 Bob 102 Class B Indicator False
3 indicator column
print("\n=== indicator=True 显示合并详情 ===")
print(result_indicator)
[/mycode4]</div>
</div>
<p><strong>运行结果预期:</strong></p>
<pre>
=== 索引作为连接键 ===
name city score subject grade
0 Alice Beijing 85 Math A
1 Bob Shanghai 90 Math B
2 Charlie Guangzhou 95 English A
3 Diana Shenzhen 88 English B
=== 多个键的合并 ===
student_id name course_id course_name score
0 1 Alice 101 Math 90
1 1 Alice 102 English 85
2 2 Bob 101 Math 88
3 2 Bob 103 Science 92
4 3 Charlie 102 English 95
=== indicator=True 显示合并详情 ===
name city merge_info
0 Alice Beijing both
1 Bob Shanghai both
2 Charlie Guangzhou left_only
3 Diana Shenzhen left_only
コード解説:
- を使用すると
left_index=Trueとright_index=TrueDataFrame のインデックスを結合キーとして使用できます。 - にリストを渡すと
onパラメータで複数キー結合が可能になり、すべてのキーが一致した場合にのみレコードが保持されます。 - を設定すると
indicator=True各レコードがどのテーブルから来たかを示す特別な列(left_only, right_only, both)を追加できます。
その他の拡張ヒント:
pd.merge()は列に基づく結合操作に適しています。単純にデータを縦方向に追加(行を増やす)だけの場合は、pd.concat()関数を使用してください。
Pandas よく使う関数