pd.merge: การเชื่อมแบบด้านในและด้านนอก
รวม DataFrames สองชุดตามคอลัมน์คีย์ร่วมด้วยการเชื่อมแบบด้านในและด้านนอก และทำความเข้าใจว่าแถวใดจะถูกเก็บหรือลบ
pd.merge: การเชื่อมแบบด้านในและด้านนอก เป็นบทเรียน Pandas & NumPy Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Pandas & NumPy Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน
join คืออะไร
join ใช้รวม DataFrame สองชุดเข้าด้วยกัน โดยจับคู่แถวตามคอลัมน์คีย์ที่มีร่วมกัน ซึ่งเป็นแนวคิดเดียวกับคำสั่ง JOIN ของ SQL Pandas ใช้ pd.merge() เพื่อดำเนินการ join ต่างจาก pd.concat() ที่เพียงนำข้อมูลมาต่อกัน pd.merge() จะจัดแนวแถวจากตารางสองชุดที่แตกต่างกันอย่างชาญฉลาด โดยอาศัยค่าที่ตรงกันในคอลัมน์อย่างน้อยหนึ่งคอลัมน์
คอลัมน์คีย์ร่วมกัน
การ merge จะทำงานได้ DataFrame ทั้งสองชุดต้องมีคอลัมน์อย่างน้อยหนึ่งคอลัมน์ที่มีค่าร่วมกัน ซึ่งเรียกว่า คอลัมน์คีย์ ตัวอย่างเช่น ตาราง orders มีคอลัมน์ customer_id และตาราง customers ก็มีคอลัมน์ customer_id เช่นกัน การ merge ด้วย customer_id จะเพิ่มรายละเอียดลูกค้าให้กับแถวคำสั่งซื้อแต่ละแถว ให้ระบุคีย์ด้วยพารามิเตอร์ on เมื่อ DataFrame ทั้งสองชุดใช้ชื่อคอลัมน์เดียวกัน
import pandas as pd
orders = pd.DataFrame({
'order_id': [1, 2, 3, 4],
'customer_id': [101, 102, 101, 103],
'amount': [250, 80, 320, 150]
})
customers = pd.DataFrame({
'customer_id': [101, 102, 104],
'name': ['Alice', 'Bob', 'Diana']
})Inner Join: จุดร่วมของตารางทั้งสอง
inner join (ค่าเริ่มต้น) จะเก็บเฉพาะแถวที่ค่าคีย์มีอยู่ใน DataFrame ทั้งสองชุด แถวในตารางใดก็ตามที่ไม่มีคีย์ตรงกันในอีกตารางจะถูกลบออกโดยไม่มีการแจ้งเตือน ในตัวอย่างคำสั่งซื้อ ลูกค้า 103 และ 104 ไม่มีรายการตรงกันในอีกตาราง ดังนั้นแถวของลูกค้าเหล่านี้จึงไม่อยู่ในผลลัพธ์ของ inner join
# Inner join (default): only matching rows from both
result = pd.merge(orders, customers, on='customer_id', how='inner')
print(result)
# order_id customer_id amount name
# 0 1 101 250 Alice
# 1 3 101 320 Alice
# 2 2 102 80 Bob
# Order 4 (customer 103) dropped - no match in customers
# Diana (customer 104) dropped - no match in ordersOuter Join: การรวมข้อมูลจากตารางทั้งสอง
outer join (how='outer') จะเก็บทุกแถวจาก DataFrame ทั้งสองชุด หากแถวใดไม่มีคีย์ที่ตรงกันในอีกตาราง คอลัมน์ที่ขาดหายไปจะถูกเติมด้วย NaN วิธีนี้มีประโยชน์เมื่อต้องการเห็นภาพข้อมูลทั้งสองชุดอย่างครบถ้วน โดยยังคงเก็บระเบียนที่จับคู่ไม่สำเร็จไว้
result = pd.merge(orders, customers, on='customer_id', how='outer')
print(result)
# order_id customer_id amount name
# 0 1.0 101 250.0 Alice
# 1 3.0 101 320.0 Alice
# 2 2.0 102 80.0 Bob
# 3 4.0 103 150.0 NaN <- order with unknown customer
# 4 NaN 104 NaN Diana <- customer with no ordersการ Merge คอลัมน์ที่มีชื่อต่างกัน
เมื่อคอลัมน์คีย์มีชื่อต่างกันใน DataFrame แต่ละชุด ให้ใช้ left_on และ right_on แทน on Pandas จะจับคู่แถวที่ค่า left_on ใน DataFrame ฝั่งซ้ายเท่ากับค่า right_on ใน DataFrame ฝั่งขวา คอลัมน์คีย์ทั้งสองจะปรากฏในผลลัพธ์ และคุณสามารถใช้ drop เพื่อลบคอลัมน์ที่ซ้ำซ้อนออกภายหลังได้
products = pd.DataFrame({
'prod_id': [10, 20, 30],
'name': ['Widget', 'Gadget', 'Doohickey']
})
order_lines = pd.DataFrame({
'item_id': [10, 10, 20],
'qty': [3, 1, 5]
})
result = pd.merge(order_lines, products,
left_on='item_id', right_on='prod_id')
print(result.drop(columns='prod_id'))
# item_id qty name
# 0 10 3 Widget
# 1 10 1 Widget
# 2 20 5 Gadgetการ Merge ด้วยหลายคอลัมน์
หากต้องการจับคู่แถวด้วยชุดผสมของคอลัมน์ (คีย์ผสม) ให้ส่งรายการไปยัง on วิธีนี้พบได้บ่อยเมื่อคอลัมน์เดียวไม่เพียงพอที่จะจับคู่ให้ไม่ซ้ำกัน เช่น การ merge ด้วยทั้ง year และ region คอลัมน์ทั้งหมดที่ระบุจะต้องตรงกันพร้อมกัน แถวนั้นจึงจะถูกรวมไว้ในผลลัพธ์
targets = pd.DataFrame({
'year': [2023, 2023, 2024],
'region': ['East', 'West', 'East'],
'target': [100, 150, 120]
})
actuals = pd.DataFrame({
'year': [2023, 2024, 2024],
'region': ['East', 'East', 'West'],
'actual': [95, 115, 80]
})
result = pd.merge(targets, actuals, on=['year', 'region'], how='inner')
print(result)
# year region target actual
# 0 2023 East 100 95
# 1 2024 East 120 115การจัดการชื่อคอลัมน์ที่ซ้ำกัน
เมื่อ DataFrame ทั้งสองชุดมีคอลัมน์ชื่อเดียวกัน (นอกเหนือจากคีย์) Pandas จะเติมส่วนต่อท้ายเพื่อแยกความแตกต่าง โดยค่าเริ่มต้นคือ _x สำหรับฝั่งซ้าย และ _y สำหรับฝั่งขวา คุณสามารถกำหนดค่าเหล่านี้เองด้วยพารามิเตอร์ suffixes เพื่อให้ได้ชื่อที่สื่อความหมายมากขึ้นและลดความสับสนในผลลัพธ์
df_a = pd.DataFrame({'id': [1, 2], 'value': [10, 20]})
df_b = pd.DataFrame({'id': [1, 2], 'value': [100, 200]})
# Default suffixes
print(pd.merge(df_a, df_b, on='id'))
# id value_x value_y
# Custom suffixes
print(pd.merge(df_a, df_b, on='id', suffixes=('_budget', '_actual')))
# id value_budget value_actualการตรวจสอบข้อมูลซ้ำที่ไม่คาดคิด
ปัญหาที่พบบ่อยในการ merge คือจำนวนแถวเพิ่มขึ้นโดยไม่คาดคิด หากคอลัมน์คีย์มีค่าซ้ำกันใน DataFrame ทั้งสองชุด การ merge จะสร้างผลคูณคาร์ทีเซียนของแถวที่ตรงกันทั้งหมด โปรดตรวจสอบจำนวนแถวหลังการ merge เสมอ หากจำนวนมากกว่าที่คาดไว้ ให้ตรวจสอบค่าซ้ำในคอลัมน์คีย์ด้วย df.duplicated(subset=['key']).sum()
# Both tables have duplicate keys -> cartesian product
left = pd.DataFrame({'id': [1, 1], 'val_l': ['a', 'b']})
right = pd.DataFrame({'id': [1, 1], 'val_r': ['x', 'y']})
result = pd.merge(left, right, on='id')
print(len(result)) # 4 rows! (2x2 cartesian product)
print(result)
# id val_l val_r
# 0 1 a x
# 1 1 a y
# 2 1 b x
# 3 1 b yพารามิเตอร์ validate เพื่อความปลอดภัย
ส่งพารามิเตอร์ validate เพื่อบังคับใช้ข้อกำหนดความสัมพันธ์ในการ merge และทำให้เกิดข้อผิดพลาดหากมีการละเมิดข้อกำหนด 'one_to_one' กำหนดให้คีย์ในตารางทั้งสองไม่ซ้ำกัน 'one_to_many' กำหนดให้คีย์ในตารางฝั่งซ้ายไม่ซ้ำกัน และ 'many_to_one' กำหนดเฉพาะคีย์ในตารางฝั่งขวา วิธีนี้เป็นแนวทางการเขียนโค้ดเชิงป้องกันที่ดีเยี่ยม เพราะช่วยตรวจพบปัญหาคุณภาพข้อมูลได้ตั้งแต่เนิ่น ๆ
# Safe merge: validate that customer_id is unique in customers
try:
result = pd.merge(orders, customers,
on='customer_id',
how='inner',
validate='many_to_one')
print('Merge OK, shape:', result.shape)
except Exception as e:
print('Merge error:', e)การตรวจสอบความครอบคลุมด้วย indicator
ส่ง indicator=True เพื่อเพิ่มคอลัมน์ _merge ให้กับผลลัพธ์ โดยคอลัมน์นี้จะแสดงว่าแต่ละแถวมาจากที่ใด: 'left_only', 'right_only' หรือ 'both' วิธีนี้มีประโยชน์หลังทำ outer join เพื่อระบุว่าระเบียนใดจับคู่ได้และระเบียนใดจับคู่ไม่ได้ ช่วยให้คุณตรวจสอบคุณภาพข้อมูลก่อนลบคอลัมน์ตัวบ่งชี้ออก
result = pd.merge(orders, customers, on='customer_id',
how='outer', indicator=True)
print(result['_merge'].value_counts())
# both 3
# left_only 1 <- orders with no customer record
# right_only 1 <- customers with no orders
# Find unmatched orders
print(result[result['_merge'] == 'left_only'])สรุป Inner กับ Outer
สรุปประเภท join ทั้งสองแบบ: inner join ให้จุดร่วม ซึ่งมีเฉพาะแถวที่มีคีย์ตรงกันใน DataFrame ทั้งสองชุด ส่วน outer join ให้การรวม ซึ่งมีทุกแถวจาก DataFrame ทั้งสองชุด และเติม NaN เมื่อไม่มีรายการตรงกัน เพื่อให้ครบถ้วน: left join จะคงทุกแถวจาก DataFrame ฝั่งซ้าย และ right join จะคงทุกแถวจาก DataFrame ฝั่งขวา โดยจะกล่าวถึงหัวข้อเหล่านี้ในบทเรียนถัดไป
# Quick reference
# how='inner' -> intersection: only matched rows
# how='outer' -> union: all rows from both, NaN for no match
# how='left' -> all left rows + matched right rows
# how='right' -> all right rows + matched left rows
# Most common: inner (default) for enrichment, left for preserving recordsตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจของคุณเกี่ยวกับ inner และ outer join ของ pd.merge จากบทเรียนนี้
ทบทวนบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า pd.merge() ที่ใช้ how='inner' จะเก็บเฉพาะแถวที่ตรงกันจาก DataFrame ทั้งสองชุด ขณะที่ how='outer' จะเก็บทุกแถวและใช้ NaN สำหรับแถวที่ไม่ตรงกัน on ใช้ระบุคีย์ร่วมกัน ส่วน left_on/right_on ใช้จัดการชื่อคอลัมน์ที่แตกต่างกัน และพารามิเตอร์ indicator ช่วยตรวจสอบว่าแถวใดจับคู่กันได้ ต่อไปเราจะสำรวจ left และ right join เพื่อคงทุกแถวจากฝั่งใดฝั่งหนึ่ง
คำถามที่พบบ่อย
บทเรียน “pd.merge: การเชื่อมแบบด้านในและด้านนอก” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “pd.merge: การเชื่อมแบบด้านในและด้านนอก” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Pandas & NumPy Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “pd.merge: การเชื่อมแบบด้านในและด้านนอก”
รวม DataFrames สองชุดตามคอลัมน์คีย์ร่วมด้วยการเชื่อมแบบด้านในและด้านนอก และทำความเข้าใจว่าแถวใดจะถูกเก็บหรือลบ คุณปฏิบัติ Pandas & NumPy Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Pandas & NumPy Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Pandas & NumPy Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “pd.merge: การเชื่อมแบบด้านในและด้านนอก” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Pandas & NumPy Academy นี้ได้ไหม
ได้ บทเรียน Pandas & NumPy Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- pd.concat สำหรับการซ้อน DataFrames
- pd.merge: การเชื่อมแบบด้านในและด้านนอก
- การเชื่อมด้านซ้ายและด้านขวา
- การเชื่อมตามดัชนี