pandas .str accessor ทำให้ผมใช้ text functions อย่าง upper, replace, contains กับทุกแถวในคอลัมน์พร้อมกันบรรทัดเดียว เหมือนได้ UPPER/SUBSTITUTE/SEARCH ของ Excel แต่ไม่ต้องลากสูตรทีละเซลล์ครับ
df['col'].str.method()
df['col'].str.method()
Series
คืน Series ใหม่ที่ผ่านการแปลงข้อความแล้วครับ — shape เหมือนเดิม แค่ค่าในแต่ละแถวถูก transform แล้ว สามารถเอาไปเก็บเป็นคอลัมน์ใหม่ด้วย df['new_col'] = … หรือใช้เป็น boolean mask กรองแถวต่อได้เลย
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| pat | str | Yes | ข้อความหรือ pattern ที่ต้องการค้นหา ใช้กับ .str.contains(pat) และ .str.replace(pat, repl) | |
| repl | str | Optional | ข้อความที่ใช้แทนที่ ใช้กับ .str.replace(pat, repl) — ตรงกับ argument ที่สองของ SUBSTITUTE ใน Excel | |
| case | bool | Optional | True | ใช้กับ .str.contains() — True คือ case-sensitive (ค่า default), False คือไม่สนตัวพิมพ์ใหญ่เล็ก |
df['name'].str.upper()df['name'].str.upper()
0 ALICE
1 BOB
2 CHARLIE
3 DIANA
Name: name, dtype: str
df[df['name'].str.contains('Alice')]df[df['name'].str.contains('Alice')]
name
0 Alice Smith
2 Alice Brown
df['email'].str.replace('@old.com', '@new.com', regex=False)df['email'].str.replace('@old.com', '@new.com', regex=False)
0 alice@new.com
1 bob@new.com
2 charlie@new.com
Name: email, dtype: str
df['full_name'].str.split(' ')df['full_name'].str.split(' ')
0 [Alice, Smith]
1 [Bob, Jones]
2 [Charlie, Brown]
Name: full_name, dtype: object
ผลลัพธ์เหมือนกันครับ แต่ .str.upper() เร็วกว่ามากเพราะ pandas ทำงานแบบ vectorized (C-level loop) ส่วน .apply(lambda) เป็น Python loop ทีละแถว ข้อมูล 1 ล้านแถว .str จะเร็วกว่า apply หลายเท่าตัวเลยครับ ผมเลยใช้ .str เป็น default และเลือก .apply เฉพาะตอนต้องการ logic ที่ .str ทำไม่ได้
ค่า default ของ .str.contains() คือ regex=True ครับ หมายความว่าถ้าใส่ pattern พิเศษอย่าง ‘alice|bob’ มันจะค้นหาแบบ regex เลย แต่ถ้าต้องการค้นหาข้อความธรรมดา (ไม่ใช่ regex) ให้ใส่ regex=False ด้วย ผมลืมใส่แล้วงงว่าทำไมผลไม่ถูกก็มีนะครับ 😅
ปกติ .str methods จะคืน NaN กลับมาสำหรับแถวที่เป็น NaN ครับ ไม่ error แต่ถ้าใช้ .str.contains() จะได้ NaN แทน True/False ซึ่งพอเอาไปกรองแถวจะ error ได้ วิธีแก้คือใส่ na=False ไปด้วย เช่น df[‘col’].str.contains(‘word’, na=False) แล้วแถว NaN จะถูกนับเป็น False แทนครับ
ใน Excel ถ้าอยากแปลงข้อความทั้งคอลัมน์ เราต้องเขียนสูตรในเซลล์แรกแล้วลากลงไปทุกแถว แต่ใน pandas เราใช้ .str accessor แล้วตามด้วย method ที่ต้องการเลย pandas จะวิ่งใส่ทุกแถวให้อัตโนมัติครับ
หลัก mental model มีง่ายๆ แค่ 3 จังหวะ:
1. เข้าถึง accessor: `df[‘col’].str` — บอก pandas ว่าเราจะทำงานกับข้อความ
2. เลือก method: `.upper()` / `.contains(pat)` / `.replace(pat, repl)` / `.len()` — เลือกตามงานที่ต้องการ
3. ได้ผลกลับเป็น Series ใหม่ — นำไปเก็บเป็นคอลัมน์ใหม่หรือใช้กรองข้อมูลต่อได้ทันที
ที่เจ๋งคือ .str.contains() คืน Series ของ True/False ซึ่งเอาไปใช้เป็น mask กรองแถวได้เลย เหมือน SEARCH ใน Excel แต่ทรงพลังกว่าเพราะรองรับ Regular Expression ด้วยครับ
ส่วนตัวผมใช้ .str บ่อยมากตอน clean ข้อมูล เช่น trim ช่องว่าง แปลง email ให้เป็น lowercase หรือดึงส่วนหนึ่งของข้อความออกมา งานที่ใน Excel ต้องเขียนสูตรซับซ้อน ใน pandas เขียนบรรทัดเดียวจบเลยครับ 😎