Merge & Join
Merge & Join
Section titled “Merge & Join”ข้อมูลจริงมักกระจายอยู่หลายตาราง — ตารางสินค้า, ตารางลูกค้า, ตารางออเดอร์
pd.merge() ช่วยเชื่อมข้อมูลเหล่านี้เข้าด้วยกัน
สร้างข้อมูลตัวอย่าง
Section titled “สร้างข้อมูลตัวอย่าง”import pandas as pd
orders = pd.DataFrame({ "order_id": [1, 2, 3, 4], "customer_id": ["C001", "C002", "C003", "C001"], "amount": [500, 1200, 350, 800]})
customers = pd.DataFrame({ "customer_id": ["C001", "C002", "C004"], "name": ["Alice", "Bob", "Diana"], "city": ["กรุงเทพ", "เชียงใหม่", "ภูเก็ต"]})pd.merge() — Inner Join (default)
Section titled “pd.merge() — Inner Join (default)”# เฉพาะแถวที่ match ทั้งสองตารางresult = pd.merge(orders, customers, on="customer_id")print(result)# order_id customer_id amount name city# 1 C001 500 Alice กรุงเทพ# 2 C002 1200 Bob เชียงใหม่# 4 C001 800 Alice กรุงเทพ# C003 หายไป (ไม่มีใน customers), C004 หายไป (ไม่มีใน orders)Left / Right Join
Section titled “Left / Right Join”# Left join — เก็บทุกแถวจากตารางซ้ายresult = pd.merge(orders, customers, on="customer_id", how="left")# C003 จะมี name=NaN, city=NaN
# Right join — เก็บทุกแถวจากตารางขวาresult = pd.merge(orders, customers, on="customer_id", how="right")# C004 จะมี order_id=NaN, amount=NaN
# Outer join — เก็บทุกแถวจากทั้งสองตารางresult = pd.merge(orders, customers, on="customer_id", how="outer")Leading-Zeros Trap
Section titled “Leading-Zeros Trap”# ปัญหาที่พบบ่อยมาก!df1 = pd.DataFrame({"code": ["001", "002", "003"], "name": ["A", "B", "C"]})df2 = pd.DataFrame({"code": [1, 2, 3], "value": [100, 200, 300]})
# merge จะไม่เจอเลย เพราะ "001" != 1bad = pd.merge(df1, df2, on="code") # Empty DataFrame!
# แก้ไข: ทำให้ type ตรงกันก่อน mergedf2["code"] = df2["code"].astype(str).str.zfill(3)good = pd.merge(df1, df2, on="code") # สำเร็จ!ตรวจสอบผลลัพธ์ merge
Section titled “ตรวจสอบผลลัพธ์ merge”# ใช้ indicator=True เพื่อดูว่าแต่ละแถวมาจากไหนresult = pd.merge(orders, customers, on="customer_id", how="outer", indicator=True)print(result["_merge"].value_counts())# both 3 ← match ทั้งคู่# left_only 1 ← มีใน orders อย่างเดียว# right_only 1 ← มีใน customers อย่างเดียว=VLOOKUP(A2, Customers!A:C, 2, FALSE)— left join 1 column=INDEX(MATCH())— ยืดหยุ่นกว่า VLOOKUP- ข้อจำกัด: ทำได้ทีละ column, ไม่มี inner/outer join
SELECT o.*, c.name, c.cityFROM orders oLEFT JOIN customers c ON o.customer_id = c.customer_id;-- Leading zeros: LPAD(code, 3, '0')// C ต้อง nested loop หรือ hash table// ไม่มี merge ดั้งเดิม — ค่อนข้างซับซ้อน