[Pandas-Part IV] Join Type , Merge และ Concatenate
การเลือกใช้ Merge และ Concat (Concatenate) เป็นอีกชุดคำสั่งที่เราจะได้ใช้กันบ่อยๆในการเตรียมข้อมูล เช่น นำข้อมูลที่มีหลายๆตาราง หรือ หลายๆไฟล์ มารวมกันได้
ก่อนที่เราจะไปดูเรื่อง Merge และ Concat จำเป็นจะต้องพูดถึงเรื่องประเภทของการ Join ก่อน ซึ่งหลักๆจะมี 4 ประเภท
Join Type
Join ก็การนำเอา 2 Tables(หรือมากกว่า 2 ก็ได้) มารวมกัน ซึ่งแน่นอนว่าการ Join จะต้องมี Key ที่จะใช้สำหรับ Join ถ้าหาก Table ที่จะ Join นั้นมี Key เหมือนกัน ผลลัพธ์ก็จะออกมาไม่เป็น Null (Join เจอ) แต่ถ้าหาก Key ที่จะ Join นั้น ไม่มีอยู่ในอีก Table ผลลัพธ์ก็จะออกมาเป็น Null (Join ไม่เจอ)
Left Join
การทำ Left Join เป็นการตั้งต้นจาก Left Table จากนั้นถ้า Join เจอ ก็ให้นำคอลัมน์ใน Right Table มาต่อตามรูปที่ 2
Right Join
การทำ Right Join เหมือนกับการทำ Left Join ทุกประการเพียงแต่สลับจากซ้ายเป็นขวา และขวาเป็นซ้าย โดยตั้งต้นจาก Right Table จากนั้นถ้า Join เจอก็ให้นำคอลัมน์ใน Left Table มาต่อตามรูปที่ 3
Inner Join
การทำ Inner Join จะตั้งต้นจาก Left Table แต่จะแสดงผลเฉพาะ Rows ที่ Join เจอเท่านั้น
Outer Join / Full Outer Join
สำหรับการทำ Full Outer Join จะเป็นเหมือนการทำ Left Join ผสม Right Join เพื่อให้แยกกันได้อย่างชัดเจนมากยิ่งขึ้นสามารถดูรูปที่ 6
จากรูปที่ 6 ตารางฝั่งขวามือ จะเห็นได้ว่ามีผลลัพธ์จาก Outer Join ทั้งหมด 3 ประเภท นั้นก็คือ
- Join เจอ หรือมี Key ที่เหมือนกันทั้ง 2 Tables
- มี Key ใน Left Table แต่ไม่มีใน Right Table : ค่าใน Right Table จะเป็น Null
- มี Key ใน Right Table แต่ไม่มีใน Left Table : ค่าใน Left Table จะเป็น Null
ตัวอย่างโจทย์ในการ Join
ตัวอย่าง Data
Left Table : เป็นข้อมูล Transactions
Right Table : เป็นข้อมูล product_info
Objective : ต้องการนำคอลัมน์ prod_cat และ prod_subcat จาก Right Table ไปรวมกับ Left Table ด้วยวิธี Left Join
Remark : ทั้ง 2 Table มีชื่อ Column ไม่เหมือนกัน
- Left Table : prod_cat_code = Right Table : prod_cat_code (เหมือนกัน)
- Left Table : prod_subcat_code = Right Table : prod_sub_cat_code (ไม่เหมือนกัน)
คำสั่ง Merge
# pd.merge(left, right, how='inner', on=None, left_on=None,
# right_on=None,left_index=False, right_index=False,
# sort=True,suffixes=('_x', '_y'), copy=True,
# indicator=False,validate=None)# merge df_transac and df_prod_info
# key df_transac = prod_cat_code , prod_subcat_code
# key df_prod_info = prod_cat_code , prod_sub_cat_code
คำสั่ง Merge หลักๆจะต้องกำนดไปว่า จะให้ Table ใดเป็น Left (left = ? ) , Table ใดเป็น Right (right = ? ) , Key ที่จะ Join อยู่ในคอลัมน์ใด (on = ?) **ในกรณีที่ชื่อ คอลัมน์ที่เก็บ Key Join ไว้อยู่ไม่เหมือนกัน จะต้องระบุให้ชัดเจนว่า Key Join ของฝั่ง Left และ ฝั่ง Right เป็นคอลัมน์ใด(left_on = ? , right_on = ? ) และที่สำคัญคือจะ Join กันด้วยวิธีอะไร ( how = ? )
df_tran_prod = pd.merge(left = df_transac , right = df_prod_info ,
left_on = ['prod_cat_code' , 'prod_subcat_code'],
right_on = ['prod_cat_code', 'prod_sub_cat_code'],
how = 'left')
df_tran_prod
จากรูปที่ 7 จะสังเกตได้ว่าเดิม df_prod_info จะมีทั้งหมด 4 คอลัมน์ แต่ทำไมผลลัพธ์ออกมาเพียง 3 คอลัมน์ ?? เนื่องจากว่ามี คอลัมน์ prod_cat_code ที่ถูกนำมาใช้เป็น key ในการ join เหมือนกัน จึงคงคอลัมน์ไว้ในเฉพาะ df_transac เท่านั้น (เพราะเราใช้วิธีการ Left Join) ซึ่งจริงๆแล้ว ถ้าหากเราจะนำ DataFrame นี้ไปใช้งานต่อ เราก็สามารถ ตัดคอลัมน์ที่ไม่ต้องการ
# drop unnecessary columns outdrop_col = ['prod_subcat_code','prod_cat_code','prod_sub_cat_code']
df_tran_prod.drop(columns=drop_col , inplace = True)
เพียงเท่านี้ หน้าตาของ Data เราก็ดูอ่านง่ายขึ้น และพร้อมมากขึ้น เราอาจจะนำไปทำ visualization ต่อได้ แต่ถ้าอยากจะนำไปสร้าง machine learning model อาจจะต้องทำการ Data Preparation ต่ออีกพอสมควร
สิ่งที่ต้องระวังในการใช้ Merge
เมื่อเวลาที่ทำการ Merge แบบ Many to Many อาจจะเกิด duplicate ซึ่งถ้าหากเราไม่ตรวจสอบให้ดีก่อนที่จะนำมา Merge แล้ว อาจจะทำให้เราวิเคราะห์ข้อมูลผิดทางได้
ตัวอย่างโจทย์ในการ Join
ตัวอย่าง Data
จากรูปที่ 9 จะเห็นได้ว่าเรามีข้อมูลทั้งหมด 3 DataFrames ซึ่งเราต้องการที่จะนำทั้ง 3 DataFrames นี้มารวมกันให้เหลือเพียง 1 DataFrame เท่านั้น
คำสั่ง Concat
Concat เป็นอีกหนึ่งคำสั่งที่ใช้ในการรวม tables ซึ่งสามารถทำได้ในลักษณะเหมือนกัน Join (คล้ายๆกับ Merge แต่ join type จะมีเพียง Inner Join และ Outer Join เท่านั้น) แต่โดยส่วนมากแล้วจะนิยมใช้ Concat ในการ Append Data มากกว่า
# pd.concat(objs, axis=0, join='outer', ignore_index=False,
# keys=None,levels=None, names=None,
# verify_integrity=False,copy=True)
argument ที่สำคัญของการ Concat คือ axis
- axis = 0 : รวม Table ในแนวตั้ง
- axis = 1 : รวม Table ในแนวนอน
ใน argument ที่ objs เราจะต้องใส่ List ของ DataFrame ที่เราต้องการจะนำมารวมกัน และกำหนด axis ว่าเราจะรวม DataFrame ในแนวอะไร
# concatenate 3 DataFrames pd.concat([df_tran_180214, df_tran_190214, df_tran_200214] , axis=0)
เพียงเท่านี้เราก็จะสามารถรวม DataFrame ทั้ง 3 ได้ตามต้องการแล้ว ซึ่งเราสามารถ ใช้ Concat ในการรวมหลาย Files ได้ จากการวน Loop อ่าน File และ Concat ไปเรื่อยๆ เพียงเท่านี้เราก็จะสามารถรวบรวมหลายๆ File ไว้ใน DataFrame เดียวกัน จากนั้นก็ Write เป็น File ใหม่ขึ้นมา เพื่อใช้งานต่อได้เลย
สิ่งที่ต้องระวังในการใช้ Concat
การทำ Concat ในกรณีที่ DataFrame มีคอลัมน์ไม่เหมือนกัน เมื่อ Concat axis = 0 แล้วอาจจะเกิดค่า Null ใน Row ที่ไม่ได้มีคอลัมน์เหมือนกับ DataFrame อื่น
สำหรับบทความนี้ก็จะมีเพียงเท่านี้ครับ สำหรับบทความหน้า จะเป็นการรวบรวมทุกๆ คำสั่งที่เราใช้กันมาตั้ง Part I จนถึง Part IV เพื่อนำมาสร้าง Customer Singleview เพื่อที่จะทำไปวิเคราะห์ต่อไม่ว่าจะเป็นการทำ Visualization การทำ Machine Learning สำหรับท่านใดที่สนใจ ก็สามารถติดตามกันได้เลยนะครับ :)