ここでは複数のデータフレームの結合演算を行います.これはリレーショナルデータベースの自然結合演算に相当します.
はじめに,モジュールをインポートします.
# モジュールのインポート
import pandas as pd
次に,3つの CSV ファイルを順番に読み込みます.まずは,販売データである machine-sales-sales.csv ファイルを読み込み,df_sales
に格納します.ここで,系列 branch_id
および staff_id
は外部キーになっており,他のデータフレームの主キー(候補キー)を参照しています.
# CSV ファイルを読み込む
url = "https://github.com/rinsaka/sample-data-sets/blob/master/machine-sales-sales.csv?raw=true"
df_sales = pd.read_csv(url, parse_dates=["date"])
df_sales
続いて,支店一覧 machine-sales-branch.csv ファイルを読み込み,df_branch
に格納します.このとき,df_branch
の主キーは id
になっており,これは df_sales
の branch_id
と関連付けられていることに注意します.
# CSV ファイルを読み込む
url = "https://github.com/rinsaka/sample-data-sets/blob/master/machine-sales-branch-id.csv?raw=true"
df_branch = pd.read_csv(url)
df_branch
さらに,営業担当者の一覧 machine-sales-staff.csv ファイルを読み込み,df_staff
に格納します.このとき,df_staff
の主キーは id
になっており,これは df_sales
の staff_id
と関連付けられていることに注意します.
# CSV ファイルを読み込む
url = "https://github.com/rinsaka/sample-data-sets/blob/master/machine-sales-staff-id.csv?raw=true"
df_staff = pd.read_csv(url)
df_staff
ここでは,今読み込んだ3つのデータフレームを結合し,次のようなデータフレームを作成してみます.
merge()
関数を利用すると,2つのデータフレームを結合することができます.しかしながら,このときデータフレームの同じ系列名を探して結合します.したがって,df_sales
と df_branch
では id
系列がありますが,id
系列では結合することができずエラーになります.
pd.merge(df_sales, df_branch)
ValueError Traceback (most recent call last)
結合時の条件になる系列を指定したい場合は left_on
と right_on
を使うことになります.つまり,df_sales
の branch_id
と df_branch
の id
を関連付けるためには,次のように指定します.
pd.merge(
df_sales, df_branch,
left_on='branch_id',
right_on='id'
)
同じ方法で,df_sales
と df_staff
を結合します.
pd.merge(
df_sales, df_staff,
left_on='staff_id',
right_on='id'
)
3つのデータフレームの結合は,まず2つのデータフレーム(df_sales
と df_branch
)を結合し,さらにその結果と3つ目のデータフレーム(df_staff
)を結合することで実現できます.この方法が理解できれば4つ以上でも結合できるはずです.
pd.merge(
pd.merge(
df_sales, df_branch,
left_on='branch_id', right_on='id'
),
df_staff,
left_on='staff_id', right_on='id'
)
上の結果で barnch_id
や staff_id
を表示する必要がないのであれば,必要な系列のみを抽出すると良いでしょう.これを関係データベースの世界では射影演算と呼びます.なお,系列の表示順も変更しています.
pd.merge(
pd.merge(
df_sales, df_branch,
left_on='branch_id', right_on='id'
),
df_staff,
left_on='staff_id', right_on='id'
)[['id_x', 'date', 'branch', 'name', 'amount']]
上で抽出した結果から新たなデータフレームを作成することももちろん可能です.
df = pd.merge(
pd.merge(
df_sales, df_branch,
left_on='branch_id', right_on='id'
),
df_staff,
left_on='staff_id', right_on='id'
)[['id_x', 'date', 'branch', 'name', 'amount']]
df
上の結果では,df_sales
にあった id
系列の名称が id_x
に変更されています(さらに,途中の段階で id_y
なども使われていたことに注意してください).データフレームの系列名を変更したい場合には,rename()
を利用します.
df = df.rename(columns={'id_x': 'id'})
df
上の結果では,id
列の表示順が変更されてしまっています.id
順にソートしてデータフレームを更新することも可能です.
df = df.sort_values(by=['id'], ascending=[True])
df