query ใน pandas ผมใช้กรองแถวใน DataFrame ด้วยข้อความเงื่อนไขที่อ่านง่ายเหมือนพูดภาษาคน แทนที่จะเขียน boolean mask ยาวๆ ให้ตาลาย เหมาะมากกับเงื่อนไขซับซ้อนหลายข้อที่อยากให้โค้ดสั้นและอ่านรู้เรื่องครับ
df.query(expr)
df.query(expr)
DataFrame
คืนเป็น DataFrame ที่กรองแถวตามเงื่อนไขแล้วครับ ใช้งานต่อได้เลย (อยากเลือกคอลัมน์ ['name'] ต่อก็ได้)
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| expr | str | Yes | นิพจน์เงื่อนไขในรูปแบบ string เช่น ‘score > 70’ หรือ ‘dept == “IT” and score >= 80’ ใช้ and/or/not สำหรับเงื่อนไขหลายข้อ |
df.query('score > 70')df.query('score > 70')
name score
0 Alice 85
2 Carol 92
3 Dave 75
df.query('dept == "IT" and score >= 80')df.query('dept == "IT" and score >= 80')
name dept score
0 Alice IT 85
2 Carol IT 92
df.query('score >= @min_score')df.query('score >= @min_score')
name score
0 Alice 85
2 Carol 92
3 Dave 75
ขึ้นกับขนาดข้อมูลครับ ถ้า DataFrame เล็ก (ต่ำกว่าหมื่นแถว) query อาจช้ากว่านิดหน่อยเพราะต้องเสียเวลาแปลง string เป็นโค้ดก่อน แต่พอข้อมูลใหญ่และเงื่อนไขซับซ้อน query กลับเร็วกว่าได้ เพราะเบื้องหลังมันใช้ numexpr ช่วยประมวลผล ส่วนตัวผมเลยไม่กังวลเรื่องความเร็วตอนทำงานข้อมูลก้อนใหญ่ครับ
ได้ครับ แค่ครอบชื่อคอลัมน์ด้วย backtick เช่น df.query(‘`first name` == “Alice”‘) แค่นี้ pandas ก็จัดการให้ถูกต้องเอง ไม่ต้องไปเปลี่ยนชื่อคอลัมน์ให้ยุ่งยาก
query เป็นเมธอดที่ผมชอบเพราะมันทำให้โค้ดกรองข้อมูลอ่านง่ายขึ้นเยอะมากครับ 😎
ลองนึกภาพ แทนที่จะเขียน df[(df[‘score’] > 70) & (df[‘dept’] == ‘IT’)] ที่ยาวและต้องคอยระวังวงเล็บ เราเขียนแค่ df.query(‘score > 70 and dept == “IT”‘) ก็ได้ผลเหมือนกัน อ่านปุ๊บเข้าใจปั๊บ
จุดที่ผมชอบ:
– ใช้ and, or, not ได้เลย ไม่ต้องมานั่งกังวลเรื่อง &, |, ~ ที่ต้องใส่วงเล็บครอบให้ถูก
– ใช้ @ชื่อตัวแปร เพื่อดึงค่าจากตัวแปรนอก DataFrame เข้ามาในเงื่อนไขได้
– ชื่อคอลัมน์ที่มีช่องว่างก็ครอบด้วย backtick เช่น `first name` ได้สบาย
ที่ต้องระวังคือ query ไม่ได้รองรับทุกนิพจน์นะครับ พวกที่ต้องเรียกฟังก์ชันแปลกๆ ที่ไม่ใช่ built-in มันทำไม่ได้ ตรงนั้นต้องกลับไปใช้ boolean mask ปกติแทน 💡