แก้ภาษาไทยเพี้ยนใน Python และ pandas

pandas อ่านภาษาไทยเป็น เธชเธง หยุดด้วย UnicodeDecodeError หรือ Excel เปิดไฟล์ CSV ที่คุณส่งออกผิดใช่ไหม ใน Python พารามิเตอร์ encoding เป็นตัวชี้ขาดว่าถูกหรือเพี้ยน ต่อไปนี้คือกรณีทั่วไป – ส่วนไฟล์ที่เสียแล้วซ่อมได้ในเบราว์เซอร์ด้านบน

รองรับข้อความและไฟล์เหล่านี้:

  • CSV
  • TXT
  • JSON
  • XML
  • SRT
  • VTT
  • SMI
  • TSV
  • MD
  • HTML
  • SQL
  • LOG

เช่น ไฟล์ส่งออกจาก Excel ข้อมูลสำรองฐานข้อมูล คำบรรยาย หรือโค้ดเว็บไซต์

แก้ไข

  1. ลากไฟล์มาวางหรือวางข้อความ
  2. แก้ให้อัตโนมัติ
  3. คัดลอกหรือดาวน์โหลด
หรือลากไฟล์มาวางที่นี่
  • ไม่ต้องอัปโหลด ไฟล์ถูกแก้ในเบราว์เซอร์ของคุณและไม่ออกจากอุปกรณ์

  • เซิร์ฟเวอร์ในสหภาพยุโรป Mojibuster ทำงานบนเซิร์ฟเวอร์ที่ ฟินแลนด์ (สหภาพยุโรป) จึงอยู่ภายใต้กฎหมายคุ้มครองข้อมูลทั่วไป (GDPR) อ่าน GDPR (EUR-Lex ภาษาอังกฤษ)

UnicodeDecodeError ตอนอ่านไฟล์

pd.read_csv คาดว่าไฟล์เป็น UTF-8 ถ้าไฟล์บันทึกเป็น TIS-620 หรือ Windows-874 (ANSI ภาษาไทย) pandas จะหยุดพร้อม UnicodeDecodeError: 'utf-8' codec can't decode byte 0xca – ไบต์ 0xCA คือ ส ใน TIS-620 ให้ระบุรหัสอักขระดังนี้:

  • pd.read_csv('data.csv', encoding='cp874') สำหรับไฟล์จาก Excel และวินโดวส์ไทย
  • encoding='tis-620' ใช้ได้เช่นกัน แต่ cp874 อ่านเครื่องหมายอย่าง … และอัญประกาศได้ด้วย
  • ถ้าไม่รู้รหัสอักขระ ให้วางไฟล์ลงใน Mojibuster: ระบบตรวจให้เองและบันทึกเป็น UTF-8

ภาษาต่างดาวแทนภาษาไทยใน DataFrame

ถ้า DataFrame แสดง เธชเธง แปลว่าไฟล์ UTF-8 ถูกอ่านด้วย cp874 หรือ latin-1 – หรือข้อมูลเสียมาก่อนแล้ว กรณีแรกแค่ใช้ encoding='utf-8' แต่ถ้าตัวข้อมูลเสียเอง value.encode('cp874').decode('utf-8') ช่วยได้กับค่าเดี่ยว ๆ แต่กับข้อมูลที่ปะปนกันจะพังทันทีที่เจอเซลล์ที่ถูกอยู่แล้ว ง่ายกว่าคือซ่อมไฟล์ด้วย Mojibuster แล้วค่อยอ่าน

CSV จาก pandas ที่เปิดใน Excel โดยไม่มี BOM

ก่อน

ª×èÍ,àÁ×ͧ,ÃÒÂä´é
ÊÁªÒ 㨴Õ,àªÕ§ãËÁè,1250
ÊØÁÒÅÕ ÃÑ¡ä·Â,¢Í¹á¡è¹,980

หลัง

ชื่อ,เมือง,รายได้
สมชาย ใจดี,เชียงใหม่,1250
สุมาลี รักไทย,ขอนแก่น,980

to_csv: Excel แสดงไฟล์ผิด

df.to_csv('export.csv') เขียน UTF-8 แบบไม่มี BOM Excel เปิดไฟล์แบบนี้เป็น ANSI และตัวอักษรไทยเพี้ยน ถ้าใช้ encoding='utf-8-sig' pandas จะเขียน BOM และ Excel จำ UTF-8 ได้ อ่านเพิ่มที่ Excel และ CSV ภาษาไทยเพี้ยน

open() บนวินโดวส์

open('file.txt') ที่ไม่มี encoding ใช้รหัสอักขระของระบบบนวินโดวส์ ซึ่งในเครื่องไทยมักเป็น cp874 สคริปต์ที่ทำงานได้บนลินุกซ์จึงอ่านไฟล์ UTF-8 เดียวกันเป็นภาษาต่างดาวบนวินโดวส์ ดังนั้นให้ใส่ encoding='utf-8' เสมอ หรือตั้งตัวแปรสภาพแวดล้อม PYTHONUTF8=1 ตาม PEP 686 Python รุ่นหลัง ๆ ก็จะใช้ UTF-8 เป็นค่าเริ่มต้นอยู่แล้ว

ข้อมูลเว็บด้วย requests

requests หา response.text จากส่วนหัว Content-Type ถ้าคำตอบที่เป็นข้อความไม่ระบุชุดอักขระตรงนั้น จะถือว่าเป็น ISO-8859-1 และหน้า UTF-8 ภาษาไทยจะกลายเป็นภาษาต่างดาว ให้ตั้ง response.encoding = 'utf-8' ก่อน หรือใช้ response.json() ซึ่งตรวจ UTF-8 ได้เอง

ถ้าข้อความถูกเขียนด้วย errors='replace' ลงรหัสอักขระที่ไม่มีตัวอักษรที่ต้องการ ไฟล์จะมี ? – กรณีนั้นข้อมูลหายไปแล้ว ดู mojibake คืออะไร

คำถามที่พบบ่อย

มีไลบรารี Python สำหรับเรื่องนี้ไหม

มี ftfy ซ่อม mojibake ในโค้ด Python ส่วนไฟล์เดี่ยว ๆ ที่ไม่อยากเขียนโปรแกรม Mojibuster เร็วกว่าและแสดงทุกการเปลี่ยนแปลงก่อนบันทึก

ค่า encoding ไหนที่ใช้บ่อยที่สุด

utf-8, utf-8-sig (UTF-8 แบบมี BOM), cp874 (วินโดวส์ไทย), tis-620, latin-1 และ utf-16 ตัวพิมพ์เล็กใหญ่และขีดกลางไม่มีผล

ตัวคั่นและตัวเลขยังอยู่ครบไหม

ครบ Mojibuster เปลี่ยนเฉพาะอักขระที่เสีย เครื่องหมายจุลภาค อัญประกาศ และการขึ้นบรรทัดใหม่คงเดิมทุกประการ

คู่มืออื่น ๆ