Data Analyst › pandas

กรองข้อมูล (filter)

ประมาณ 25 นาที

เป้าหมายของบท

  • กรองแถวด้วยเงื่อนไขเปรียบเทียบและ &/|/~
  • ใช้ isin() และ between() แทนเงื่อนไขยาวๆ
  • กรองข้อความด้วย .str.contains()

เงื่อนไข boolean และการรวมหลายเงื่อนไข

products[products['price'] > 1000]

products['price'] > 1000 ได้ Series ของค่า True/False (หนึ่งค่าต่อแถว) — เอา Series นี้ไปใส่ใน [...] เพื่อกรองเฉพาะแถวที่เป็น True

รวมหลายเงื่อนไขด้วย:

ตัวดำเนินการ ความหมาย
& AND (ต้องจริงทั้งคู่)
| OR (จริงอย่างน้อยหนึ่ง)
~ NOT (กลับค่าความจริง)

สำคัญมาก: ต้องใส่วงเล็บรอบแต่ละเงื่อนไขย่อยเสมอ:

products[(products['category'] == 'Home') & (products['price'] <= 1000)]

ถ้าลืมวงเล็บ Python จะตีความ &/| ก่อน ==/</> ทำให้เกิด error หรือผลลัพธ์ที่ไม่ตรงกับที่ตั้งใจ (ต่างจาก SQL ที่ AND/OR มีความสำคัญต่ำกว่าตัวเปรียบเทียบอยู่แล้ว โดยไม่ต้องใส่วงเล็บ)

isin() แทนเงื่อนไข == หลายอัน

customers[customers['city'].isin(['Phuket', 'Hat Yai'])]

เขียนสั้นกว่า (customers['city'] == 'Phuket') | (customers['city'] == 'Hat Yai') และอ่านง่ายกว่ามาก เมื่อมีค่าที่ต้องเทียบหลายค่า

between() แทนช่วงตัวเลข

products[products['price'].between(500, 1000)]

เทียบเท่ากับ (products['price'] >= 500) & (products['price'] <= 1000) — รวมขอบทั้งสองด้าน

กรองข้อความด้วย .str.contains()

customers[customers['email'].str.contains('00042')]

.str เปิดทางเข้าฟังก์ชันจัดการข้อความของ pandas ทั้งหมด (.str.contains, .str.startswith, .str.strip, .str.upper ฯลฯ) — จะได้ใช้เต็มๆ ในบทที่ 7 ตอนทำความสะอาดข้อมูล

ตัวอย่างแก้โจทย์

กด "ขั้นต่อไป" ทีละขั้น ลองรันและแก้โค้ดในแต่ละขั้นได้

สินค้าหมวด Home ราคาไม่เกิน 1000 บาท (รวมสองเงื่อนไขด้วย &)

อยากดูสินค้าหมวด Home ที่ราคาไม่แพงเกินไป (ไม่เกิน 1000 บาท)

  1. ลองกรองเงื่อนไขเดียวก่อน (แค่หมวด)

    Python

ลูกค้าจากเมือง Phuket หรือ Hat Yai (ใช้ isin แทน | ยาวๆ)

อยากดูลูกค้าจากสองเมืองนี้พร้อมกัน

  1. เขียนแบบยาวด้วย | (OR) ก่อน

    Python

เติมช่องว่าง

แทน ___ ด้วยโค้ดที่ถูกต้อง แล้วกดตรวจคำตอบ

ยังไม่ได้ทำ

สินค้าราคาระหว่าง 500 ถึง 1000 บาท เก็บไว้ในตัวแปร result เติม ___ ให้ครบ

แบบฝึกท้ายบท

บทนี้จะนับว่าเสร็จเมื่อผ่านข้อพื้นฐานและประยุกต์ครบ ข้อท้าทายได้ดาวเพิ่ม

🟢 พื้นฐาน

🟢 พื้นฐานยังไม่ได้ทำ

สินค้าหมวด Home ราคาไม่เกิน 1000 บาท แสดง product_name, price เก็บไว้ในตัวแปร result

🟢 พื้นฐานยังไม่ได้ทำ

จำนวนออเดอร์ที่จ่ายด้วย promptpay หรือ cod เก็บไว้ในตัวแปร n_orders

🟢 พื้นฐานยังไม่ได้ทำ

จำนวนออเดอร์ที่ไม่ใช่สถานะ cancelled (ใช้ ~) เก็บไว้ในตัวแปร n_not_cancelled

🟢 พื้นฐานยังไม่ได้ทำ

จำนวนลูกค้าที่อยู่เมือง Chiang Mai หรือ Khon Kaen (ใช้ isin) เก็บไว้ในตัวแปร n_customers

🟡 ประยุกต์

🟡 ประยุกต์ยังไม่ได้ทำ

สินค้าราคาระหว่าง 500-1000 บาท ในหมวด Home หรือ Sports เก็บไว้ในตัวแปร n_products

🟡 ประยุกต์ยังไม่ได้ทำ

ลูกค้าที่อีเมลมีคำว่า "00042" (ใช้ .str.contains) แสดง customer_id, email เก็บไว้ในตัวแปร result

🟡 ประยุกต์ยังไม่ได้ทำ

จำนวนออเดอร์ที่มีส่วนลด หรือ ถูกยกเลิก (สองเงื่อนไขนี้ไม่ตัดกันหมด บางออเดอร์เข้าทั้งคู่) เก็บไว้ในตัวแปร n_orders

🔴 ท้าทาย

🔴 ท้าทายยังไม่ได้ทำ

สินค้าหมวด Electronics ราคาอยู่ระหว่าง 1000 ถึง 20000 บาท (ไม่รวม 20000 พอดี) เก็บไว้ในตัวแปร n_products

Quiz

1. ทำไม products['price'] > 500 & products['price'] < 1000 ถึง error
2. isin(['A', 'B']) เทียบเท่ากับอะไร
3. ~ ทำหน้าที่อะไร

สรุป

  • รวมหลายเงื่อนไขด้วย &/|/~ ต้องใส่วงเล็บรอบแต่ละเงื่อนไขเสมอ เพราะ & และ | มีความสำคัญสูงกว่า ==/</>
  • isin([...]) แทนเงื่อนไข == เชื่อมด้วย | หลายๆ อัน ได้สั้นและอ่านง่ายกว่า
  • between(a, b) เช็คว่าค่าคอลัมน์อยู่ในช่วง a ถึง b (รวมขอบทั้งสองด้าน)

คำถามสัมภาษณ์

จะกรองข้อมูลด้วยหลายเงื่อนไขใน pandas อย่างอ่านง่ายและไม่ error ทำยังไง

ใส่วงเล็บรอบแต่ละเงื่อนไขเสมอเมื่อใช้ &/|/~ (เพราะ Python ให้ตัวดำเนินการเหล่านี้มีความสำคัญสูงกว่า ==/</>) ใช้ isin() แทนเงื่อนไข == หลายอันที่เชื่อมด้วย | และใช้ between() แทนการเขียน (col >= a) & (col <= b) เต็มรูปแบบ เมื่อเงื่อนไขซับซ้อนมากจริงๆ อาจพิจารณาใช้ .query() แทนเพื่อความอ่านง่าย