Filter Rows by Rule
filter_rows · rows · any
2026-09-23
กำลังประมวลผล…
filter_rows · rows · any
2026-09-23
งานทำความสะอาดจำนวนมากจบลงที่ "เอาเฉพาะแถวที่เข้าเงื่อนไข" เช่น เฉพาะปีนี้ เฉพาะลูกค้าที่อายุถึงเกณฑ์ หรือเฉพาะแถวที่มีอีเมล เทคนิคนี้รวมเงื่อนไขหลายข้อไว้ในขั้นตอนเดียว และบอกจำนวนแถวที่จะหายไปก่อนคุณกดใช้จริง
validate_regex ซึ่งทำเครื่องหมายไว้ก่อนได้โดยไม่ลบทันทีis_null และ not_null ตรวจค่าว่างโดยตรง ส่วนตัวดำเนินการอื่นจะถือว่าแถวที่ค่าเป็น null ไม่ผ่านเงื่อนไขเสมอ"ไม่ระบุ" เทียบกับ "18" แบบข้อความจึงให้ผลว่ามากกว่า ซึ่งมักไม่ใช่สิ่งที่ตั้งใจ ให้ใช้ convert_type ก่อนเพื่อให้คอลัมน์เป็นตัวเลขจริงcombine แล้วเก็บหรือลบตาม action| Parameter | Type | Default |
|---|---|---|
conditions | object[] | — |
combine | AND | OR | "AND" |
action | keep | remove | "keep" |
import json
import re
def to_number(value):
if isinstance(value, bool) or value is None:
return None
if isinstance(value, (int, float)):
return value
if isinstance(value, str) and re.fullmatch(r'[+-]?(\d+\.?\d*|\.\d+)', value.strip().replace(',', '')):
return float(value.strip().replace(',', ''))
return None
def evaluate(value, operator, operand):
if operator == 'is_null':
return value is None
if operator == 'not_null':
return value is not None
if value is None:
return False
left, right = to_number(value), to_number(operand)
both = left is not None and right is not None
if not both:
left, right = str(value), operand
if operator == 'eq':
return left == right
if operator == 'neq':
return left != right
if operator == 'gt':
return left > right
if operator == 'gte':
return left >= right
if operator == 'lt':
return left < right
if operator == 'lte':
return left <= right
if operator == 'contains':
return operand in str(value)
return operand not in str(value)
def filter_rows(rows, conditions, combine='AND', action='keep'):
def matches(row):
results = [evaluate(row.get(c['column']), c['operator'], c['value']) for c in conditions]
return all(results) if combine == 'AND' else any(results)
return [row for row in rows if matches(row) == (action == 'keep')]
rows = [
{'name': 'A', 'age': '20'},
{'name': 'B', 'age': '17'},
{'name': 'C', 'age': None},
{'name': 'D', 'age': 'ไม่ระบุ'},
]
conditions = [{'column': 'age', 'operator': 'gte', 'value': '18'}]
print(json.dumps(filter_rows(rows, conditions), ensure_ascii=False))
สังเกตผลลัพธ์ของโค้ดด้านบน แถว D ที่อายุเป็น "ไม่ระบุ" ถูกเก็บไว้ด้วย เพราะเมื่อฝั่งใดฝั่งหนึ่งไม่ใช่ตัวเลข ระบบจะเทียบแบบข้อความ วิธีที่ถูกคือรัน convert_type ให้ age เป็น integer ก่อน แล้วค่าที่แปลงไม่ได้จะกลายเป็น null ซึ่งไม่ผ่านเงื่อนไข gte ตามที่คาด
ใช้ convert_type ก่อนกรองด้วยตัวเลขหรือวันที่เสมอ ใช้ remove_missing_rows เมื่อเงื่อนไขคือแค่ "ต้องมีค่า" และใช้ validate_regex เมื่ออยากทำเครื่องหมายก่อนตัดสินใจลบ