UnicodeDecodeError เมื่ออ่านไฟล์ CSV ใน Pandas ด้วย Python


411

ฉันใช้งานโปรแกรมที่กำลังประมวลผลไฟล์ที่คล้ายกัน 30,000 ไฟล์ จำนวนสุ่มจะหยุดและสร้างข้อผิดพลาดนี้ ...

   File "C:\Importer\src\dfman\importer.py", line 26, in import_chr
     data = pd.read_csv(filepath, names=fields)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 400, in parser_f
     return _read(filepath_or_buffer, kwds)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 205, in _read
     return parser.read()
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 608, in read
     ret = self._engine.read(nrows)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 1028, in read
     data = self._reader.read(nrows)
   File "parser.pyx", line 706, in pandas.parser.TextReader.read (pandas\parser.c:6745)
   File "parser.pyx", line 728, in pandas.parser.TextReader._read_low_memory (pandas\parser.c:6964)
   File "parser.pyx", line 804, in pandas.parser.TextReader._read_rows (pandas\parser.c:7780)
   File "parser.pyx", line 890, in pandas.parser.TextReader._convert_column_data (pandas\parser.c:8793)
   File "parser.pyx", line 950, in pandas.parser.TextReader._convert_tokens (pandas\parser.c:9484)
   File "parser.pyx", line 1026, in pandas.parser.TextReader._convert_with_dtype (pandas\parser.c:10642)
   File "parser.pyx", line 1046, in pandas.parser.TextReader._string_convert (pandas\parser.c:10853)
   File "parser.pyx", line 1278, in pandas.parser._string_box_utf8 (pandas\parser.c:15657)
 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xda in position 6: invalid    continuation byte

แหล่งที่มา / การสร้างไฟล์เหล่านี้ทั้งหมดมาจากที่เดียวกัน วิธีที่ดีที่สุดในการแก้ไขสิ่งนี้เพื่อดำเนินการนำเข้าต่อไปคืออะไร

คำตอบ:


823

read_csvใช้encodingตัวเลือกเพื่อจัดการกับไฟล์ในรูปแบบที่แตกต่างกัน ผมส่วนใหญ่ใช้read_csv('file', encoding = "ISO-8859-1")หรืออีกทางเลือกหนึ่งencoding = "utf-8"สำหรับการอ่านและโดยทั่วไปสำหรับutf-8to_csv

คุณยังสามารถใช้หนึ่งในหลาย ๆaliasตัวเลือกเช่น'latin'แทน'ISO-8859-1'(ดูpython docsรวมถึงการเข้ารหัสอื่น ๆ ที่คุณอาจพบ)

ดูเอกสารที่เกี่ยวข้องนุ่น , หลามเอกสารตัวอย่างไฟล์ CSVและความอุดมสมบูรณ์ของคำถามที่เกี่ยวข้องกับที่นี่ใน SO ทรัพยากรพื้นหลังที่ดีเป็นสิ่งที่นักพัฒนาทุกคนควรรู้เกี่ยวกับ Unicode และตัวอักษรชุด

ในการตรวจจับการเข้ารหัส (สมมติว่าไฟล์มีอักขระที่ไม่ใช่ ASCII) คุณสามารถใช้enca(ดูman page ) หรือfile -i(linux) หรือfile -I(osx) (ดูman page )


7
เนื่องจากนี่เป็นปัญหาของ Windows จึงcp1252อาจเป็นที่นิยมiso-8859-1มากกว่า
tzot

7
ขอบคุณpd.read_csv('immigration.csv', encoding = "ISO-8859-1", engine='python')ทำงานให้ฉัน
Mona Jalal

8
อย่าคาดเดาว่าการเข้ารหัสบางอย่างเป็นสิ่งที่ถูกต้องเพียงเพราะสุ่มไม่มีข้อยกเว้น คุณต้องดูที่สตริงและหาว่าการตีความนั้นสมเหตุสมผลหรือไม่ ตัวอย่างเช่นหากคุณได้รับ "hors d'½uvre" แทน "hors d'œuvre" คุณอาจต้องเปลี่ยนจาก ISO-8859-1 เป็น ISO-8859-15
Joachim Wagner

6
ANSIสำหรับผมการเข้ารหัสเป็น ในการคิดออกฉันเปิด csv notepadจากนั้นคลิกที่save asนั่นมันแสดงการเข้ารหัสข้างปุ่มบันทึก
Vaibhav Vishal


68

วิธีแก้ปัญหาที่ง่ายที่สุด:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')

ทางเลือกอื่น:

  • เปิดไฟล์ CSV ในโปรแกรมแก้ไขข้อความ Sublime
  • บันทึกไฟล์ในรูปแบบ utf-8

ในประเสริฐคลิกไฟล์ -> บันทึกด้วยการเข้ารหัส -> UTF-8

จากนั้นคุณสามารถอ่านไฟล์ได้ตามปกติ:

import pandas as pd
data = pd.read_csv('file_name.csv', encoding='utf-8')

และประเภทการเข้ารหัสอื่น ๆ ได้แก่ :

encoding = "cp1252"
encoding = "ISO-8859-1"

11
คำถามอธิบายว่ามีไฟล์ดังกล่าว 30,000 ไฟล์ การเปิดแต่ละไฟล์ด้วยตนเองจะไม่สามารถใช้งานได้จริง
Keith

4
อย่างน้อยหนึ่งไฟล์ดูเหมือนจะเหมาะกับฉัน!
apil.tamang

เอ็นจิ้นซีเห็นได้ชัดว่าให้อภัยในสิ่งที่ยอมรับ สำหรับไฟล์ CSV โดยเฉพาะอย่างยิ่งที่เปิดดีกับencoding='iso-8859-1'การใช้แทนพ่นengine='python' _csv.Error: field larger than field limit (131072)
เกร็กเบคอน

1
ทางเลือกอื่นในการใช้บันทึกพร้อมการเข้ารหัสมีประโยชน์จริง ๆ ! นี่คือวิธีใช้สำหรับ VSCode stackoverflow.com/questions/30082741/…
brownmagik352

20

Pandas อนุญาตให้ระบุการเข้ารหัส แต่ไม่อนุญาตให้ละเว้นข้อผิดพลาดที่จะไม่แทนที่ไบต์ที่ละเมิดโดยอัตโนมัติ ดังนั้นจึงไม่มีขนาดที่เหมาะกับวิธีการทั้งหมดแต่วิธีที่แตกต่างกันขึ้นอยู่กับกรณีการใช้งานจริง

  1. คุณรู้การเข้ารหัสและไม่มีข้อผิดพลาดในการเข้ารหัสไฟล์ เยี่ยมมาก: คุณต้องระบุการเข้ารหัส:

    file_encoding = 'cp1252'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
  2. คุณไม่ต้องการที่จะใส่ใจกับคำถามการเข้ารหัสและต้องการให้ไฟล์ด่าโหลดเท่านั้นไม่ว่าฟิลด์ข้อความบางไฟล์จะมีขยะ ตกลงคุณจะต้องใช้การLatin1เข้ารหัสเพราะมันยอมรับไบต์ใด ๆ ที่เป็นไปได้เป็นอินพุต (และแปลงเป็นอักขระ Unicode ของรหัสเดียวกัน):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
  3. คุณรู้ว่าไฟล์ส่วนใหญ่เขียนด้วยการเข้ารหัสเฉพาะ แต่มันก็มีข้อผิดพลาดในการเข้ารหัสด้วย ตัวอย่างโลกแห่งความจริงคือไฟล์ UTF8 ที่ได้รับการแก้ไขด้วยโปรแกรมแก้ไขที่ไม่ใช่ utf8 และมีบางบรรทัดที่มีการเข้ารหัสที่แตกต่างกัน Pandas ไม่มีข้อกำหนดสำหรับการประมวลผลข้อผิดพลาดพิเศษ แต่openฟังก์ชั่นPython มี (สมมติว่า Python3) และread_csvยอมรับไฟล์เช่นวัตถุ พารามิเตอร์ข้อผิดพลาดทั่วไปที่จะใช้ที่นี่เป็น'ignore'เพียงการระงับไบต์ที่กระทำผิดหรือ (ดีกว่า IMHO) 'backslashreplace'ซึ่งแทนที่ไบต์ที่กระทำผิดโดยลำดับแบ็กสแลช Python:

    file_encoding = 'utf8'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    input_fd = open(input_file_and_path, encoding=file_encoding, errors = 'backslashreplace')
    pd.read_csv(input_fd, ...)

1
ตอบช้ากว่า แต่ถูกกำหนดเป้าหมายไปที่คำถามที่ซ้ำกัน ...
Serge Ballesta

14
with open('filename.csv') as f:
   print(f)

หลังจากรันโค้ดนี้คุณจะพบการเข้ารหัสของ 'filename.csv' จากนั้นรันโค้ดดังต่อไปนี้

data=pd.read_csv('filename.csv', encoding="encoding as you found earlier"

ไปแล้ว


6

ในกรณีของฉันไฟล์มีการUSC-2 LE BOMเข้ารหัสตาม Notepad ++ มันมีencoding="utf_16_le"ไว้สำหรับหลาม

หวังว่าจะช่วยให้หาคำตอบได้เร็วขึ้นสำหรับใครบางคน


4

ในกรณีของฉันสิ่งนี้ใช้ได้กับ python 2.7:

data = read_csv(filename, encoding = "ISO-8859-1", dtype={'name_of_colum': unicode}, low_memory=False) 

และสำหรับ python 3 เท่านั้น:

data = read_csv(filename, encoding = "ISO-8859-1", low_memory=False) 

3

ลองระบุ engine = 'python' มันใช้งานได้สำหรับฉัน แต่ฉันยังคงพยายามหาสาเหตุ

df = pd.read_csv(input_file_path,...engine='python')

มันก็ใช้ได้กับฉันเช่นกัน ดังนั้นการเข้ารหัส = "ISO-8859-1" มันเป็นปัญหาการเข้ารหัสอย่างแน่นอน หากมีการเข้ารหัสอักขระพิเศษใน ANSI เช่นอักขระวงรี (เช่น "... ") และคุณลองอ่านใน UTF-8 คุณอาจได้รับข้อผิดพลาด บรรทัดล่างคือคุณต้องรู้การเข้ารหัสไฟล์ที่สร้างขึ้นด้วย
Sean McCarthy

3

ฉันกำลังโพสต์คำตอบเพื่อให้การแก้ปัญหาที่ปรับปรุงและคำอธิบายว่าทำไมปัญหานี้สามารถเกิดขึ้นได้ สมมติว่าคุณได้รับข้อมูลนี้จากฐานข้อมูลหรือสมุดงาน Excel หากคุณมีอักขระพิเศษเช่นLa Cañada Flintridge cityกันยกเว้นว่าคุณกำลังส่งออกข้อมูลโดยใช้การUTF-8เข้ารหัสคุณจะแนะนำข้อผิดพลาด จะกลายเป็นLa Cañada Flintridge city La Ca\xf1ada Flintridge cityหากคุณใช้pandas.read_csvโดยไม่มีการปรับเปลี่ยนพารามิเตอร์เริ่มต้นคุณจะพบข้อผิดพลาดต่อไปนี้

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 5: invalid continuation byte

โชคดีที่มีวิธีแก้ปัญหาสองสามข้อ

ตัวเลือก 1แก้ไขการส่งออก ต้องแน่ใจว่าใช้การUTF-8เข้ารหัส

ตัวเลือกที่ 2ถ้าการแก้ไขปัญหาการส่งออกไม่สามารถใช้ได้กับคุณและคุณจำเป็นต้องใช้ให้แน่ใจว่าจะรวมถึงพารามิเตอร์ต่อไปนี้pandas.read_csv engine='python'โดยค่าเริ่มต้นแล้วแพนด้าจะใช้engine='C'ซึ่งเหมาะสำหรับการอ่านไฟล์สะอาดขนาดใหญ่ แต่จะเกิดปัญหาหากมีสิ่งใดที่ไม่คาดคิดเกิดขึ้น จากประสบการณ์ของผมตั้งค่าไม่เคยได้รับการแก้ไขนี้encoding='utf-8' UnicodeDecodeErrorนอกจากนี้คุณไม่จำเป็นต้องใช้errors_bad_linesอย่างไรก็ตามนั่นยังคงเป็นตัวเลือกหากคุณต้องการจริงๆ

pd.read_csv(<your file>, engine='python')

ตัวเลือก 3:โซลูชันเป็นโซลูชันที่ฉันต้องการเป็นการส่วนตัว อ่านไฟล์โดยใช้ vanilla Python

import pandas as pd

data = []

with open(<your file>, "rb") as myfile:
    # read the header seperately
    # decode it as 'utf-8', remove any special characters, and split it on the comma (or deliminator)
    header = myfile.readline().decode('utf-8').replace('\r\n', '').split(',')
    # read the rest of the data
    for line in myfile:
        row = line.decode('utf-8', errors='ignore').replace('\r\n', '').split(',')
        data.append(row)

# save the data as a dataframe
df = pd.DataFrame(data=data, columns = header)

หวังว่านี่จะช่วยให้ผู้คนประสบปัญหานี้เป็นครั้งแรก


2

ดิ้นรนกับสิ่งนี้และคิดว่าฉันโพสต์คำถามนี้เพราะมันเป็นผลการค้นหาครั้งแรก การเพิ่มencoding="iso-8859-1"แท็กให้กับแพนด้าread_csvไม่ทำงานหรือการเข้ารหัสอื่น ๆ ทำให้ UnicodeDecodeError

หากคุณผ่านการจัดการไฟล์pd.read_csv(),ที่คุณต้องการที่จะนำแอตทริบิวต์บนเปิดไฟล์ไม่ได้อยู่ในencoding read_csvชัดเจนในการเข้าใจถึงปัญหาหลัง แต่มีข้อผิดพลาดเล็กน้อยในการติดตาม


2

โปรดลองเพิ่ม

encoding='unicode_escape'

สิ่งนี้จะช่วยได้ ทำงานให้ฉัน นอกจากนี้ตรวจสอบให้แน่ใจว่าคุณใช้ชื่อตัวคั่นและคอลัมน์ที่ถูกต้อง

คุณสามารถเริ่มต้นด้วยการโหลดเพียง 1,000 แถวเพื่อโหลดไฟล์อย่างรวดเร็ว


1

คำตอบนี้น่าจะเป็นปัญหาทั้งหมดสำหรับการเข้ารหัส CSV หากคุณพบปัญหาการเข้ารหัสที่ผิดปกติกับส่วนหัวของคุณเช่นนี้:

>>> f = open(filename,"r")
>>> reader = DictReader(f)
>>> next(reader)
OrderedDict([('\ufeffid', '1'), ... ])

จากนั้นคุณจะมีอักขระเครื่องหมายคำสั่งซื้อ (BOM) ที่จุดเริ่มต้นของไฟล์ CSV ของคุณ คำตอบนี้แก้ไขปัญหา:

Python อ่าน csv - BOM ฝังอยู่ในคีย์แรก

ทางออกคือการโหลด CSV ด้วยencoding="utf-8-sig":

>>> f = open(filename,"r", encoding="utf-8-sig")
>>> reader = DictReader(f)
>>> next(reader)
OrderedDict([('id', '1'), ... ])

หวังว่านี่จะช่วยใครซักคน


1

ฉันโพสต์การอัปเดตของเธรดเก่านี้ ฉันพบโซลูชันหนึ่งที่ทำงานได้ แต่ต้องเปิดแต่ละไฟล์ ฉันเปิดไฟล์ csv ของฉันใน LibreOffice เลือกบันทึกเป็น> แก้ไขการตั้งค่าตัวกรอง ในเมนูแบบเลื่อนลงฉันเลือกการเข้ารหัส UTF8 จากนั้นฉันเพิ่มลงencoding="utf-8-sig"ในdata = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig")ไป

หวังว่านี่จะช่วยใครซักคน


Nisse ขอบคุณสำหรับการแก้ไข คุณช่วยอธิบายสิ่งที่คุณเปลี่ยนไปได้ไหม ฉันไม่เห็นความแตกต่าง
tshirtdr1

1

ฉันมีปัญหาในการเปิดไฟล์ CSV เป็นภาษาจีนตัวย่อที่ดาวน์โหลดมาจากธนาคารออนไลน์ฉันได้ลองlatin1แล้วฉันได้ลองiso-8859-1แล้วฉันได้ลองcp1252แล้วทั้งหมดก็ไม่มีประโยชน์

แต่ pd.read_csv("",encoding ='gbk')ใช้งานได้ง่าย


0

ฉันกำลังใช้ Jupyter-notebook และในกรณีของฉันมันแสดงไฟล์ในรูปแบบที่ผิด ตัวเลือก 'การเข้ารหัส' ไม่ทำงาน ดังนั้นฉันบันทึก csv ในรูปแบบ utf-8 และใช้งานได้


0

ลองสิ่งนี้:

import pandas as pd
with open('filename.csv') as f:
    data = pd.read_csv(f)

ดูเหมือนว่ามันจะดูแลการเข้ารหัสโดยไม่ต้องแสดงมันอย่างชัดเจนผ่านการโต้แย้ง


0

ตรวจสอบการเข้ารหัสก่อนที่จะส่งไปยังแพนด้า มันจะทำให้คุณช้าลง แต่ ...

with open(path, 'r') as f:
    encoding = f.encoding 

df = pd.read_csv(path,sep=sep, encoding=encoding)

ใน python 3.7


0

ปัญหาสำคัญอีกข้อที่ฉันต้องเผชิญซึ่งทำให้เกิดข้อผิดพลาดเดียวกันคือ:

_values = pd.read_csv("C:\Users\Mujeeb\Desktop\file.xlxs")

^ บรรทัดนี้ทำให้เกิดข้อผิดพลาดเดียวกันเพราะฉันกำลังอ่านไฟล์ excel โดยใช้read_csv()วิธีการ ใช้read_excel()สำหรับการอ่าน. xlxs


ว้าวคนอื่นกำลังพูดถึงปัญหาการเข้ารหัส ดูเหมือนว่าปัญหาของฉันเป็นเรื่องแปลก
Mujeeb Ishaque

เป็นเพราะคุณมีread_excelนุ่น
Ani Menon

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.