1. 実データの取得と結合
学習目標
- 公開データを複数取得して Colab に取り込める
pd.concatで複数の DataFrame を縦方向に連結できるpd.mergeで共通キーを使って横方向に結合できる- 内部結合・外部結合の違いを理解し、目的に応じて選べる
本文
実データは「複数ファイル」が普通
教科書のサンプルデータは 1 ファイルに整っていますが、実際の業務や研究では 「データは複数のファイルに分かれている」 ことの方が普通です。
- 営業の月次データが月ごとに別 CSV
- ユーザー情報と購入履歴が別テーブル
- 政府統計が「人口」「世帯」「産業」と別ダウンロード
これらを分析にかける前にやることが、本単元のテーマ 「結合」 です。pandas には、状況に応じた 2 種類の結合方法が用意されています。
| やりたいこと | 関数 | 例 |
|---|---|---|
| 縦に積み増す(同じ列構成のファイルを連結) | pd.concat | 月別 CSV を 1 つに |
| 横に広げる(同じレコードに別ファイルの列を追加) | pd.merge | ユーザー情報に購入履歴の列を加える |
pd.concat — 縦方向の連結
「列構成が同じデータフレームを縦に積み増したい」ときは pd.concat を使います。例として、社員リストが 2 つの CSV に分かれている状況を考えます。
worker1.csv:
名前, 年齢
太郎, 25
花子, 30
worker2.csv:
名前, 年齢
一郎, 22
次郎, 28
両方をそれぞれ読み込んで縦に結合:
import pandas as pd
df_worker1 = pd.read_csv("/content/drive/MyDrive/datasets/worker1.csv")
df_worker2 = pd.read_csv("/content/drive/MyDrive/datasets/worker2.csv")
df_workers = pd.concat([df_worker1, df_worker2], axis=0, ignore_index=True)
df_workers
結果:
名前 年齢
0 太郎 25
1 花子 30
2 一郎 22
3 次郎 28
axis=0— 縦方向(行を追加)に連結。axis=1だと横方向(列を追加)ignore_index=True— 連結後のインデックスを 0 から振り直す。指定しないと元のインデックスが残り、0, 1, 0, 1のように重複することがある
pd.merge — 共通キーで横方向に結合
「ユーザー情報」と「購入履歴」のように 別ファイルだが共通の鍵(キー)でつながる データを 1 つにまとめるのが pd.merge です。
jobs.csv:
名前, 職業
太郎, エンジニア
花子, デザイナー
一郎, PR
四郎, マーケティング
df_workers(先ほどの 4 名)と職業データを「名前」で結合:
df_jobs = pd.read_csv("/content/drive/MyDrive/datasets/jobs.csv")
result = pd.merge(df_workers, df_jobs, on="名前", how="inner")
result
on="名前"— 結合に使うキー列。両方の DataFrame に同じ名前の列があるhow="inner"— 結合の種類(後述)
結合の種類(how パラメータ)
merge の最重要パラメータが how です。両方のファイルにある人だけ残すか、片方にしかいない人も残すかを切り替えます。
how | 残すもの | 用途 |
|---|---|---|
"inner" | 両方にあるキーだけ(積集合) | 「両方の情報が揃った行だけ分析したい」 |
"left" | 左の DataFrame にあるキー全部 | 「ユーザーリスト基準で、購入履歴は分かる範囲だけ付ける」 |
"right" | 右の DataFrame にあるキー全部 | left と対称 |
"outer" | どちらかにあるキー全部(和集合) | 「すべての登場人物を残し、欠けてる部分は NaN」 |
先ほどの例を how="outer" で結合すると:
pd.merge(df_workers, df_jobs, on="名前", how="outer")
結果(イメージ):
名前 年齢 職業
0 太郎 25 エンジニア
1 花子 30 デザイナー
2 一郎 22 PR
3 次郎 28 NaN ← df_jobs に「次郎」がない
4 四郎 NaN マーケティング ← df_workers に「四郎」がない
「左右どちらか片方にしかない名前」が NaN として残ります。
キー名が違うときの結合
両方の DataFrame で結合キーの 列名が異なる ときは left_on / right_on を使います:
pd.merge(
df_workers,
df_companies,
left_on="名前",
right_on="社員名",
how="inner",
)
このとき、結果には「名前」と「社員名」の両方の列が残ります(中身は同じ)。片方を drop() で消すか、事前に列名を揃えると後段がきれいです。
取得 → 結合 → 分析の一連の流れ
実データの取り扱いは、おおむね次の順で進みます:
- 取得:複数の公開データを Colab に読み込む(入門講座 #3 で扱った方法)
- 整形:列名や型を揃える(入門講座 #6, #7)
- 結合:
concatやmergeで 1 つの DataFrame に - 分析:集計・可視化・統計処理(次の単元以降)
「分析を始める前のセットアップ」までを 1 つの作業として捉え、再現できるようにノートブックの上から順に書く習慣を付けましょう。
よく出る躓きどころ
concatでインデックスが重複する —ignore_index=Trueを付けるconcatで列構成が違うと NaN が大量発生 — 縦結合する DataFrame は列名・列数を揃えてからmergeでデータが激減する —how="inner"でキーの一致が少ないと、結合結果が空に近づく。how="outer"で確認するか、両方のdf["キー"].unique()で確認してから結合- 結合キーの表記揺れ — 「太郎」と「太郎 」(末尾スペース)は別物。事前に
.str.strip()で空白除去
サンプルコード
演習
3 つの CSV を Colab に読み込み、次を順に行いなさい。
worker1.csvとworker2.csvをpd.concatで縦結合し、df_workersを作るdf_workersとjobs.csvを「名前」をキーにpd.mergeで結合する(how="inner")- 同じ結合を
how="left"/how="right"/how="outer"で行い、結果の行数と NaN の位置を比べる - 結合結果を CSV として書き出す(
index=False)
3 番で 4 種類の how を試すことで、「結合の種類で何が残るか」が体感できます。実データでは「片方にしかいないレコードを残すべきか落とすべきか」が分析の方向性を左右します。
発展課題(オプション)
- 自分の関心ある分野で公開データを 2 つ以上ダウンロードし、共通キー(地域名、年など)で結合してみる
- 結合後に集計(
groupby)と可視化を 1 つ走らせ、次単元の EDA への接続を試す pd.mergeのvalidate引数("one_to_one","one_to_many"ほか)を試して、結合関係の制約を検証する