🐍

(学習ログ)Python022:pandasで複数のマスターデータを結合する方法

に公開

1. はじめに

この記事では、pandasのmerge()を使って複数のマスターデータを順次結合する方法を学びます。

実務でよくある「顧客マスター」「クラスマスター」「キャンペーンマスター」などを利用ログと結びつけるパターンを例に、データ結合の基本から結合後の確認方法までを解説します。結合の仕組みを理解すれば、データ分析の幅が一気に広がります。

2. サンプルコード

コード全文

import pandas as pd

# 利用ログデータを読み込む
sample_usagelog = pd.read_csv('003_サンプル/usage_log.csv')

# 顧客マスターを読み込む
sample_customer = pd.read_csv('003_サンプル/customer_master.csv')

# クラスマスターを読み込む
sample_class_master = pd.read_csv('003_サンプル/class_master.csv')

# キャンペーンマスターを読み込む
sample_campaign_master = pd.read_csv('003_サンプル/campaign_master.csv')

# 顧客マスターとクラスマスターを結合(class列をキーに)
sample_customer_join = pd.merge(sample_customer, sample_class_master, on="class", how="left")

# さらにキャンペーンマスターを結合(campaign_id列をキーに)
sample_customer_join = pd.merge(sample_customer_join, sample_campaign_master, on="campaign_id", how="left")

# 結合後のデータの先頭5行を表示
sample_customer_join.head()

# 元の顧客マスターの行数を確認
print(len(sample_customer))

# 結合後のデータの行数を確認
print(len(sample_customer_join))

# 欠損値の数を列ごとに確認
sample_customer_join.isnull().sum()

コード解説

■ データの読み込み(1〜8行目)

4つのCSVファイルを読み込んでいます。
それぞれの役割は

  • usage_log.csv:利用ログ(今回は未使用)
  • customer_master.csv:顧客の基本情報
  • class_master.csv:顧客クラス(ランク)の詳細情報
  • campaign_master.csv:キャンペーンの詳細情報

なぜ複数のファイルに分けるのか?
データベース設計の基本で、情報を正規化することで更新の手間を減らし、データの一貫性を保ちます。例えば、クラス名を変更したい場合、1つのマスターファイルだけ修正すればOKです。

■ 1回目の結合:顧客×クラス(10行目)

sample_customer_join = pd.merge(sample_customer, sample_class_master, on="class", how="left")

pd.merge()の引数:

  • 第1引数:左側のデータフレーム(ここでは顧客マスター)
  • 第2引数:右側のデータフレーム(ここではクラスマスター)
  • on="class":結合のキーとなる列名
  • how="left"左外部結合(左側のデータは全て残す)

初心者がつまずきやすいポイント:
how="left"は「左側のデータを優先する」という意味です。右側にマッチするデータがなくても、左側の行は残ります(該当列はNaNになる)。

■ 2回目の結合:結果×キャンペーン(13行目)

sample_customer_join = pd.merge(sample_customer_join, sample_campaign_master, on="campaign_id", how="left")

1回目の結合結果に、さらにキャンペーンマスターを結合します。このように、merge()を連続して使うことで3つ以上のデータを結合できます。

■ データの確認(16〜22行目)

結合後は必ず確認が必要です:

  • .head():先頭5行を目視確認
  • len():行数の変化をチェック(意図しない増減がないか)
  • .isnull().sum():欠損値の発生を確認

実行結果例

# 結合前の顧客マスター行数
1000

# 結合後の行数
1000

# 欠損値の確認結果
customer_id         0
customer_name       0
class               0
class_name          0
campaign_id        50
campaign_name      50
dtype: int64

結果の読み方:

  • 行数が変わっていない → 1対1の結合に成功
  • campaign_idに50件の欠損 → 50人の顧客はキャンペーンに参加していない

3. エラーと確認のポイント

代表的なエラー

❌ KeyError: 'class'

KeyError: 'class'

原因: 結合キーとして指定した列名が、どちらか(または両方)のデータフレームに存在しない。

対処法:

# 列名を確認
print(sample_customer.columns)
print(sample_class_master.columns)

スペルミスや大文字小文字の違いがないかチェックしましょう。

❌ 行数が意図せず増える

print(len(sample_customer))      # 1000
print(len(sample_customer_join)) # 1500(増えてしまった!)

原因: 結合キーが重複していて、1対多の関係になっている。

対処法:

# キーの重複を確認
sample_class_master['class'].duplicated().sum()

❌ MergeError

MergeError: No common columns to perform merge on

原因: onパラメータを指定せず、かつ共通の列名がない。

対処法: 左右で列名が異なる場合はleft_onright_onを使用:

pd.merge(df1, df2, left_on='id', right_on='customer_id', how='left')

よく使う確認メソッド

1. .info() - データ構造の概要確認

sample_customer_join.info()

出力例:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 6 columns):
 #   Column          Non-Null Count  Dtype 
---  ------          --------------  ----- 
 0   customer_id     1000 non-null   int64 
 1   customer_name   1000 non-null   object
 2   class           1000 non-null   object
 3   class_name      1000 non-null   object
 4   campaign_id     950 non-null    float64
 5   campaign_name   950 non-null    object

データ型と欠損値の有無を一目で確認できます。

2. .duplicated() - 重複行のチェック

# 重複行の数を確認
sample_customer_join.duplicated().sum()

# 特定の列での重複確認
sample_customer_join.duplicated(subset=['customer_id']).sum()

出力例:

0  # 重複なし

3. .describe() - 数値列の統計情報

sample_customer_join.describe()

出力例:

       customer_id  campaign_id
count   1000.000000   950.000000
mean     500.500000    25.300000
std      288.819436    14.500000
min        1.000000     1.000000
max     1000.000000    50.000000

結合後の数値データの分布を確認し、異常値がないかチェックできます。

4. .value_counts() - カテゴリの分布確認

sample_customer_join['class'].value_counts()

出力例:

Gold      350
Silver    300
Bronze    250
Platinum  100
Name: class, dtype: int64

結合後のカテゴリバランスが想定通りか確認できます。

4. まとめ

  • pd.merge()を使った基本的なデータ結合方法onhowパラメータの使い方を習得できました
  • 複数テーブルの段階的な結合パターン:2回以上のmergeを連続して実行する実践的な手法を学びました
  • 結合後の必須チェック項目:行数・欠損値・データ型の確認方法を理解できました
  • 実務でよくあるエラーと対処法:KeyErrorや行数増加など、典型的なトラブルに対応できるようになりました

Discussion