dropna ใน pandas ผมใช้สำหรับกำจัดแถวหรือคอลัมน์ที่มีค่า NaN ออกจาก DataFrame ครับ เหมาะมากสำหรับขั้นตอนทำความสะอาดข้อมูลก่อนวิเคราะห์ เพราะค่า NaN แฝงอยู่ในข้อมูลจริงแทบทุกชุด
df.dropna(axis, how, subset, inplace)
df.dropna(axis, how, subset, inplace)
DataFrame
คืน DataFrame ใหม่ที่ลบแถว (หรือคอลัมน์) ที่มี NaN ออกแล้วครับ ไม่แก้ของเดิม สามารถ chain ต่อได้เลย เช่น df.dropna().reset_index(drop=True)
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| axis | int | str | Optional | 0 | 0 หรือ ‘index’ = ลบแถว (default), 1 หรือ ‘columns’ = ลบคอลัมน์ที่มี NaN |
| how | str | Optional | 'any' | ‘any’ = ลบถ้ามี NaN อย่างน้อย 1 ช่อง (default), ‘all’ = ลบเฉพาะถ้าทุกช่องเป็น NaN |
| thresh | int | Optional | None | กำหนดจำนวนค่าที่ไม่ใช่ NaN ขั้นต่ำที่แถวต้องมี ถ้าต่ำกว่านี้จะถูกลบออก |
| subset | str | list | Optional | None | ระบุชื่อคอลัมน์ที่จะตรวจสอบ NaN ถ้าไม่ระบุจะตรวจทุกคอลัมน์ |
| inplace | bool | Optional | False | True = แก้ไข DataFrame ตัวเดิม และคืนค่า None, False = คืน DataFrame ใหม่ (default) |
df.dropna()df.dropna()
name score grade
0 Alice 85.0 A
2 Charlie 90.0 A
df.dropna(how='all')df.dropna(how='all')
name score grade
0 Alice 85.0 A
1 Bob NaN B
3 David 92.0 A
df.dropna(subset=['name', 'age'])df.dropna(subset=['name', 'age'])
name age phone
0 Alice 25.0 0812345678
2 Charlie 30.0 0898765432
3 David 28.0 NaN
df.dropna(axis=1)df.dropna(axis=1)
id name score
0 1 Alice 85.0
1 2 Bob 90.0
2 3 Charlie 78.0
ต่างกันที่ strategy ครับ dropna คือ “ลบแถวที่มีปัญหาออกไปเลย” ส่วน fillna คือ “เติมค่าแทนตรงที่ว่าง” ผมเลือกแบบนี้ครับ: ถ้าข้อมูลว่างจริงๆ ไม่มีทางเดาได้ หรือแถวนั้นไม่มีประโยชน์เลย → ใช้ dropna แต่ถ้าพอเดาได้ เช่น เติม 0, เติม median, หรือ forward fill → ใช้ fillna เพราะข้อมูลมีค่า จะทิ้งไปดูสิ้นเปลือง
ต่อด้วย .reset_index(drop=True) ครับ เช่น df.dropna().reset_index(drop=True) ใส่ drop=True เพื่อไม่ให้ index เก่าไปเป็นคอลัมน์ใหม่ ผมทำแบบนี้ทุกครั้งก่อนส่ง DataFrame ต่อไปให้โค้ดอื่นครับ เพราะบางครั้ง index ที่กระโดดทำให้ .iloc[] กับ .loc[] ให้ผลต่างกันแบบที่ไม่ตั้งใจ
ผมแนะนำ df = df.dropna() มากกว่าครับ เพราะ inplace=True แก้ตัวแปรเดิมทันทีและคืน None ทำให้ถ้าเขียน df = df.dropna(inplace=True) จะได้ None กลับมาแทน ซึ่งงง มากๆ ครับ นอกจากนี้ pandas กำลังทำให้ inplace deprecated ในบางกรณี ฉะนั้นเขียน df = df.dropna() ปลอดภัยกว่าเยอะ
ข้อมูลจากโลกจริงแทบไม่เคยสมบูรณ์ครับ มีค่าว่าง (NaN) กระจายอยู่ทั่วไป ไม่ว่าจะมาจากฟอร์มที่ลูกค้ากรอกไม่ครบ ระบบ export ที่ข้อมูลบางช่องหาย หรือแค่ผู้ใช้ข้ามไป dropna เป็น method ที่ใช้ลบแถวหรือคอลัมน์ที่มีค่าว่างออกได้ในคำสั่งเดียวครับ
วิธีใช้หลักๆ มี 4 รูปแบบที่ผมเจอบ่อย: (1) ลบทุกแถวที่มี NaN อย่างน้อย 1 ช่อง (default), (2) ลบเฉพาะแถวที่ทุกช่องเป็น NaN (how=’all’), (3) ระบุคอลัมน์ที่สนใจด้วย subset เพื่อไม่ให้คอลัมน์อื่นส่งผล, (4) ใช้ axis=1 เพื่อลบคอลัมน์แทนแถว
ที่เจ๋งคือ dropna คืน DataFrame ใหม่เสมอ ไม่แก้ของเดิม (ถ้าไม่ใส่ inplace=True) เพราะงั้นผมใช้สบายใจครับ เดิมยังอยู่ ผลใหม่เก็บในตัวแปรใหม่
ผมมักเปรียบ dropna กับ Excel ว่าคือการ filter ออกแถวที่ว่าง แต่ทำถาวรกว่า และรองรับโลจิกซับซ้อนกว่าเยอะครับ ถ้าอยากเติมค่าแทนการลบ ให้ดู fillna แทนนะครับ 😎