DataFrame
คืนเป็น DataFrame ใหม่ที่รวมคอลัมน์จากทั้งสองตารางไว้ด้วยกันครับ ไม่แก้ไขตารางต้นฉบับ (left/right ยังอยู่เหมือนเดิม) สามารถ chain ต่อได้ทันทีเช่น .dropna() หรือ .reset_index()
| อาร์กิวเมนต์ | ชนิด | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
| left | DataFrame | ตารางซ้าย — ตารางหลักที่เป็นฐาน | |
| right | DataFrame | ตารางขวา — ตารางที่จะนำมาเสริมข้อมูลให้ตารางซ้าย | |
| [on]ไม่บังคับ | str | list | ชื่อคอลัมน์ที่ใช้จับคู่ (ต้องมีอยู่ในทั้งสองตาราง) เช่น on=’id’ หรือ on=[‘year’,’month’] | |
| [how]ไม่บังคับ | str | 'inner' | รูปแบบ join: ‘inner’ (เฉพาะที่จับคู่ได้), ‘left’ (รักษาซ้ายทั้งหมด), ‘right’ (รักษาขวาทั้งหมด), ‘outer’ (เอาทุกแถวจากทั้งสองตาราง) |
| [left_on]ไม่บังคับ | str | list | ชื่อคอลัมน์ฝั่งซ้ายที่ใช้จับคู่ ใช้คู่กับ right_on เมื่อคอลัมน์ key มีชื่อต่างกันสองตาราง | |
| [right_on]ไม่บังคับ | str | list | ชื่อคอลัมน์ฝั่งขวาที่ใช้จับคู่ ใช้คู่กับ left_on เมื่อคอลัมน์ key มีชื่อต่างกันสองตาราง |
[ ] = อาร์กิวเมนต์ที่ไม่บังคับ
ถ้าผมจะอธิบาย merge ให้เข้าใจเร็วที่สุด คือมันคือ “VLOOKUP ที่ทำได้ถูกต้องตั้งแต่แรก” — แทนที่จะดึงทีละคอลัมน์ด้วย VLOOKUP/XLOOKUP ใน Excel, merge รวมทั้งตารางซ้ายและขวาเข้าหากันโดยจับคู่ตาม key ที่กำหนด แล้วคืนออกมาเป็น DataFrame ใหม่ที่มีทุกคอลัมน์ของทั้งสองตารางพร้อมกันครับ
สอนแบบ 3 จังหวะให้จำง่ายนะครับ:
– จังหวะที่ 1 **Left + Right**: เลือกสองตารางที่จะรวม — ตารางซ้ายคือฐาน ตารางขวาคือแหล่งข้อมูลที่จะดึงมาเสริม
– จังหวะที่ 2 **on= / left_on= + right_on=**: บอกว่าจับคู่ด้วยคอลัมน์อะไร ถ้าชื่อเหมือนกันทั้งสองตารางใช้ on= อย่างเดียว ถ้าชื่อต่างกันต้องบอกทั้ง left_on และ right_on
– จังหวะที่ 3 **how=**: เลือกสไตล์ join — inner (เอาเฉพาะที่จับคู่ได้), left (เอาซ้ายทั้งหมด), right, outer (เอาทั้งหมด)
ที่เจ๋งคือ how=’left’ คือเวทมนตร์ที่ผมใช้บ่อยที่สุดในงานจริงครับ — รักษาทุกแถวของตารางซ้ายไว้เสมอ ถ้าตารางขวาไม่มีข้อมูลก็ได้ NaN กลับมา ไม่หายไปไหน เหมาะมากกับงานที่ข้อมูลอาจไม่ครบทุกฝั่ง ส่วนตัวผมใช้ merge เกือบทุกวันตอนทำ data pipeline ครับ 😎
ผมมีตารางคำสั่งซื้อ (left) กับตารางข้อมูลสินค้า (right) รวมกันด้วย product_id ได้ DataFrame ใหม่ที่มีทั้ง qty, product_name, price ในแถวเดียวกันเลยครับ — order_id=4 หายไปเพราะ product_id=104 ไม่มีในตารางขวา นั่นคือพฤติกรรมปกติของ inner join
เพิ่ม how='left' ครับ คราวนี้ทุกแถวของตารางซ้ายถูกรักษาไว้หมด order_id=4 ยังอยู่ แต่ product_name และ price กลายเป็น NaN เพราะไม่มีข้อมูลฝั่งขวา ผมใช้แบบนี้บ่อยมากตอนอยากรู้ว่า "มีออเดอร์ไหนที่ยังไม่มีข้อมูลสินค้าบ้าง"
ผมจับคู่ด้วยสองคอลัมน์พร้อมกัน — year และ month — เพื่อดึงเป้า (target) มาเทียบกับยอดจริง (sales) ในแต่ละเดือนครับ เดือน 2024-02 ไม่มี target จึงได้ NaN กลับมา ใช้ list ใส่ใน on= ได้เลย ง่ายมาก
ตารางซ้ายเรียก 'cust_id' แต่ตารางขวาเรียก 'customer_id' ครับ ถ้าใช้ on= จะ error เลย ต้องบอกแยกด้วย left_on กับ right_on แทน ผลลัพธ์จะมีทั้งสองคอลัมน์นี้อยู่ด้วย (เก็บทั้งคู่ไว้ให้เราตัดสินใจเองว่าจะ drop อันไหน)
ต่างกันหลักๆ ที่ทิศทางครับ concat ต่อแถวหรือคอลัมน์โดยไม่ต้องจับคู่ — เอาตาราง A กับ B มาวางต่อกัน เหมือน Ctrl+V ใน Excel merge ต่างกันตรงที่ต้องมี key ร่วม แล้วมันจะจับคู่แถวให้ เหมาะกับงาน "เพิ่มข้อมูลจากอีกตารางโดยอิงตามรหัสร่วมกัน" ครับ
pandas จะ expand ออกครับ เช่น order_id 1 ตารางซ้ายกับ product_id 101 ตารางขวาที่มี 2 แถว — ผลลัพธ์จะได้ 2 แถวสำหรับ order_id 1 เลย เหมือนการ cartesian join ในส่วนนั้น ผมเจอปัญหานี้บ่อยตอน data ไม่ clean ครับ ถ้าไม่ต้องการผลแบบนี้ต้อง deduplicate ตารางขวาก่อน merge
เพราะ pandas เก็บทั้งสองไว้ให้ครับ ตัวมันเองไม่รู้ว่าเราอยากได้อันไหน ผมมักจะ drop อันที่ redundant ต่อท้ายด้วย .drop(columns=['customer_id']) เพื่อให้ DataFrame สะอาดขึ้น หรือบางทีก็ rename ไปเลยตามต้องการ
ฟังก์ชันที่ผู้เขียนโยงไว้กับ pandas merge จัดกลุ่มตามหมวด · ชี้ที่ชื่อใดชื่อหนึ่ง แล้วฟังก์ชันที่ใช้คู่กันจะมีจุดทอง
pd.concat ผมใช้สำหรับนำ DataFrame หลายตัวมาเชื่อมต่อกัน จะต่อแนวตั้ง (กองแถว) หรือแนวนอน (เพิ่มคอลัมน์) ก็ได้ ถ้าใครเคยใช้ Power Query ใน Excel แล้ว Append Queries คือตัวเทียบเคียงที่ใกล้เคียงที่สุดครับ
groupby ใน pandas ผมใช้สำหรับจัดกลุ่มข้อมูลใน DataFrame แล้วคำนวณค่าสรุปในแต่ละกลุ่ม เช่น หาผลรวม ค่าเฉลี่ย หรือค่าสถิติต่างๆ ตามหมวดหมู่ที่กำหนด ถ้าใครเคยใช้ PivotTable ใน Excel มาก่อน บอกเลยว่าตัวนี้คือเครื่องมือสายเดียวกันเลยครับ
ยังไม่มีบทความที่เกี่ยวข้องกับฟังก์ชันนี้
Comments
อีเมลของคุณจะไม่ถูกเผยแพร่