概要(pandas の join は「インデックスで横に結合」する最短ルート)
DataFrame.join は、“インデックス”をキーにして横方向(列を増やす)へ結合します。SQL の JOIN に似ていますが、基本は「インデックス同士を合わせる」点が違いです。最重要ポイントは「インデックスを整える」「how(left/inner/outer/right)を選ぶ」「列名の衝突に備える(suffix)」「型を一致させる」。これだけで、意図通りに安全な結合ができます。
基本(join の考え方と最小例)
最小例(共通インデックスで横に結合)
import pandas as pd
df1 = pd.DataFrame({"A": [10, 20, 30]}, index=[1, 2, 3])
df2 = pd.DataFrame({"B": [100, 200, 300]}, index=[2, 3, 4])
out = df1.join(df2) # デフォルトは how="left"
print(out)
# index: 1,2,3 が基準。2,3 は B が付き、1 は B が欠損、4 は捨てられる
Pythonjoin は左側の DataFrame のインデックスを基準に結合します。合わないものは欠損(NaN)になります。
列をキーにして結合(左は列で、右はインデックス)
left = pd.DataFrame({"id":[1,2,3], "A":[10,20,30]})
right = pd.DataFrame({"B":[100,200,300]}, index=[1,2,4]) # 右は index がキー
out = left.join(right, on="id") # 左は列 "id"、右は index
print(out)
Pythonon を使うと「左は指定列、右はインデックス」で結合できます。右側も列で結合したいときは set_index で整えます。
結合方法の選び方(left/inner/outer/right の違い)
how の意味(抜けと重なりをどう扱うか)
df1 = pd.DataFrame({"A":[10,20,30]}, index=[1,2,3])
df2 = pd.DataFrame({"B":[100,200,300]}, index=[2,3,4])
print(df1.join(df2, how="left")) # 左の index を残す(1,2,3)
print(df1.join(df2, how="inner")) # 共通のみ(2,3)
print(df1.join(df2, how="outer")) # 全部(1,2,3,4)
print(df1.join(df2, how="right")) # 右の index を残す(2,3,4)
Python- left(デフォルト):レポート基準が左にあるときの定番
- inner:両方に存在するキーのみ(分析で“共通部分だけ”比較)
- outer:抜けを許して“全量俯瞰”
- right:右を基準(左の代わりに右を軸にしたいとき)
インデックスを整える(set_index と on の使い分け)
右も列で結合したいなら両方 set_index
left = pd.DataFrame({"id":[1,2,3], "A":[10,20,30]})
right = pd.DataFrame({"id":[2,3,4], "B":[100,200,300]})
out = left.set_index("id").join(right.set_index("id"), how="left").reset_index()
print(out)
Python両方のキーが列にあるなら、先に set_index してから join が最短です。終わったら reset_index で元に戻します。
複合キー(複数列)で結合する
left = pd.DataFrame({"store":["A","A","B"], "month":["Jan","Feb","Jan"], "sales":[100,120,90]})
right = pd.DataFrame({"store":["A","B"], "month":["Jan","Jan"], "target":[110,95]})
out = left.set_index(["store","month"]).join(
right.set_index(["store","month"]), how="left").reset_index()
print(out)
Python複数列をキーにしたいときも「set_index(複数列)→join」が読みやすく安全です。
複数 DataFrame の同時結合と列名衝突(lsuffix/rsuffix)
まとめて 2 つ以上を結合する
base = pd.DataFrame({"A":[1,2,3]}, index=[1,2,3])
d1 = pd.DataFrame({"B":[10,20,30]}, index=[1,3,4])
d2 = pd.DataFrame({"C":[100,200,300]}, index=[2,3,5])
out = base.join([d1, d2], how="outer")
print(out)
Pythonリストで渡すと、一度に複数を結合できます。基準は最初の DataFrame のインデックスです。
列名が重なるときはサフィックスで解決
df1 = pd.DataFrame({"val":[1,2,3]}, index=[1,2,3])
df2 = pd.DataFrame({"val":[10,20,30]}, index=[2,3,4])
out = df1.join(df2, how="outer", lsuffix="_left", rsuffix="_right")
print(out)
Python同名列があるとエラーや上書きの原因になります。lsuffix/rsuffix で衝突を回避します。
時系列・カテゴリの実践例(整列→結合が品質を決める)
時系列のリサンプル後に join(粒度を揃える)
import pandas as pd
sales = pd.Series([100,120,80], index=pd.to_datetime(["2025-01-01","2025-01-02","2025-01-04"]))
users = pd.Series([50,60,55], index=pd.to_datetime(["2025-01-01","2025-01-03","2025-01-04"]))
# 日次に揃えてから結合
s_daily = sales.resample("D").sum()
u_daily = users.resample("D").sum()
out = s_daily.to_frame("sales").join(u_daily.to_frame("users"), how="outer")
print(out)
Python頻度を揃えずに join するとズレます。resample などで“比較可能な軸”へ整えてから結合します。
マスタ結合(コード→名前)で可読化
facts = pd.DataFrame({"store_id":[1,2,1], "sales":[100,120,90]})
master = pd.DataFrame({"store_id":[1,2], "store_name":["Tokyo","Osaka"]})
out = facts.set_index("store_id").join(master.set_index("store_id"), how="left").reset_index()
print(out)
PythonID と名称の突き合わせは join の王道。キーの型一致(int/str)に注意します。
つまずき対策(重複インデックス・欠損・型の一致・sort・mergeとの使い分け)
重複インデックスは“多対多結合”になる
左や右のキーが重複していると、行が増えます(直積的に結合)。意図なら OK、そうでなければ事前に drop_duplicates でユニーク化します。
欠損は NaN になる(後工程で埋めるか落とす)
outer/left/right では欠損が出ます。fillna で埋めるか、必要に応じて欠損行を除外します。
型を揃える(int と str の不一致は結合不能)
キーの dtype が違うと合流しません。astype で一致させてから結合します。
sort は結果の順序を整えるだけ
join(sort=True) は結合後のインデックスをソートします。計算結果は変わらないので、見やすさのために使います。
merge との使い分け
- join:インデックス基準で横結合(時系列・主キーが index にあるとき最短)
- merge:列基準で柔軟に結合(on/left_on/right_on、複雑なキー指定に強い) 列キーでの結合が複雑なら merge、インデックス基準で短く書けるなら join。
まとめ(「インデックスをキーに整える→how を選ぶ→衝突と型を管理」で意図通りに結合)
pandas の join は、インデックスを基準に横方向へ結合する最短手段です。set_index でキーを揃え、how で欠損・抜けの扱いを決め、lsuffix/rsuffix で列名衝突を避け、dtype を一致させる。複数 DataFrame も一度に結合でき、時系列は頻度整形→join が鉄板。列基準の柔軟な結合が必要なら merge を選ぶ。これらの型を守れば、初心者でも“短くて安全”な結合処理が安定して書けます。
