UnicodeDecodeError khi đọc tệp CSV trong Pandas bằng Python


411

Tôi đang chạy một chương trình đang xử lý 30.000 tệp tương tự. Một số ngẫu nhiên trong số họ đang dừng và tạo ra lỗi này ...

   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

Nguồn / tạo của các tệp này đều đến từ cùng một nơi. Cách tốt nhất để sửa lỗi này để tiến hành nhập khẩu là gì?

Câu trả lời:


823

read_csvcó một encodingtùy chọn để đối phó với các tập tin trong các định dạng khác nhau. Tôi chủ yếu sử dụng read_csv('file', encoding = "ISO-8859-1"), hoặc thay thế encoding = "utf-8"cho việc đọc, và nói chung utf-8cho to_csv.

Bạn cũng có thể sử dụng một trong một số aliastùy chọn như 'latin'thay vì 'ISO-8859-1'(xem tài liệu python , cũng như nhiều mã hóa khác mà bạn có thể gặp phải).

Xem tài liệu về Pandas có liên quan , ví dụ về tài liệu python trên các tệp csv và rất nhiều câu hỏi liên quan ở đây trên SO. Một tài nguyên nền tốt là những gì mọi nhà phát triển nên biết về unicode và bộ ký tự .

Để phát hiện mã hóa (giả sử tệp chứa các ký tự không phải mã ascii), bạn có thể sử dụng enca(xem trang man ) hoặc file -i(linux) hoặc file -I(osx) (xem trang man ).


7
Vì đây là vấn đề của Windows, cp1252nên có thể thích hợp hơn iso-8859-1.
tzot

7
Cảm ơn pd.read_csv('immigration.csv', encoding = "ISO-8859-1", engine='python')đã làm việc cho tôi
Mona Jalal

8
Đừng mù quáng cho rằng một mã hóa nhất định là đúng chỉ vì không có ngoại lệ được ném. Bạn cần nhìn vào các chuỗi và tìm hiểu xem việc giải thích có hợp lý hay không. Ví dụ: nếu bạn nhận được "hors d'½uvre" thay vì "hors d'œuvre", có lẽ bạn cần phải chuyển từ ISO-8859-1 sang ISO-8859-15.
Joachim Wagner

6
đối với tôi mã hóa là ANSI. Để tìm ra nó, tôi đã mở csv notepadsau đó nhấp vào save as, ở đó nó hiển thị mã hóa bên cạnh nút lưu.
Vaibhav Vishal


68

Đơn giản nhất trong tất cả các giải pháp:

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

Giải pháp thay thế:

  • Mở tệp csv trong trình soạn thảo văn bản Sublime .
  • Lưu tệp ở định dạng utf-8.

Trong cao siêu, Nhấp vào Tệp -> Lưu bằng mã hóa -> UTF-8

Sau đó, bạn có thể đọc tệp của mình như bình thường:

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

và các loại mã hóa khác nhau là:

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

11
Câu hỏi giải thích rằng có 30.000 tập tin như vậy. Mở từng tệp bằng tay sẽ không thực tế.
Keith

4
ít nhất là cho một tập tin, điều này dường như làm việc cho tôi!
apil.tamang

Công cụ C rõ ràng là dễ tha thứ hơn trong những gì nó chấp nhận. Đối với một tệp CSV cụ thể mở tốt với encoding='iso-8859-1', sử dụng thay vì engine='python'ném _csv.Error: field larger than field limit (131072).
Greg Bacon

1
giải pháp thay thế để sử dụng lưu với mã hóa là thực sự hữu ích! Dưới đây là cách sử dụng nó cho VSCode stackoverflow.com/questions/30082741/ cấp
brownmagik352

20

Pandas cho phép chỉ định mã hóa, nhưng không cho phép bỏ qua các lỗi không tự động thay thế các byte vi phạm. Vì vậy, không có một kích thước phù hợp với tất cả các phương pháp nhưng các cách khác nhau tùy thuộc vào trường hợp sử dụng thực tế.

  1. Bạn biết mã hóa và không có lỗi mã hóa trong tệp. Tuyệt vời: bạn chỉ cần xác định mã hóa:

    file_encoding = 'cp1252'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
    
  2. Bạn không muốn bị làm phiền với các câu hỏi mã hóa và chỉ muốn tải tệp chết tiệt đó, bất kể một số trường văn bản có chứa rác hay không. Ok, bạn chỉ phải sử dụng Latin1mã hóa vì nó chấp nhận bất kỳ byte nào có thể làm đầu vào (và chuyển đổi nó thành ký tự unicode của cùng một mã):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
  3. Bạn biết rằng hầu hết các tập tin được viết với một mã hóa cụ thể, nhưng nó cũng chứa lỗi mã hóa. Một ví dụ trong thế giới thực là một tệp UTF8 đã được chỉnh sửa bằng trình soạn thảo không utf8 và chứa một số dòng có mã hóa khác. Pandas không có quy định xử lý lỗi đặc biệt, nhưng openhàm Python có (giả sử Python3) và read_csvchấp nhận một tệp giống như đối tượng. Tham số lỗi điển hình được sử dụng ở đây là 'ignore'chỉ loại bỏ các byte vi phạm hoặc (IMHO tốt hơn) 'backslashreplace'thay thế các byte vi phạm bằng chuỗi thoát bị gạch chéo ngược của 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
Trả lời muộn, nhưng bị nhắm vào một câu hỏi trùng lặp ...
Serge Ballesta

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

Sau khi thực thi mã này, bạn sẽ tìm thấy mã hóa 'filename.csv', sau đó thực thi mã như sau

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

bạn đi đây


6

Trong trường hợp của tôi, một tệp có USC-2 LE BOMmã hóa, theo Notepad ++. Nó encoding="utf_16_le"dành cho trăn.

Hy vọng, nó sẽ giúp tìm ra câu trả lời nhanh hơn một chút cho ai đó.


4

Trong trường hợp của tôi, điều này làm việc cho python 2.7:

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

Và đối với python 3, chỉ:

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

3

Hãy thử chỉ định động cơ = 'python'. Nó làm việc cho tôi nhưng tôi vẫn đang cố gắng tìm hiểu tại sao.

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

Điều này cũng làm việc cho tôi. Mã hóa = "ISO-8859-1" cũng vậy. Đó chắc chắn là một vấn đề mã hóa. Nếu một ký tự đặc biệt được mã hóa trong ANSI, chẳng hạn như ký tự hình elip (tức là "...") và bạn cố đọc nó trong UTF-8, bạn có thể gặp lỗi. Dòng dưới cùng là bạn phải biết mã hóa tập tin được tạo ra.
Sean McCarthy

3

Tôi đang đăng một câu trả lời để cung cấp một giải pháp cập nhật và giải thích về lý do tại sao vấn đề này có thể xảy ra. Giả sử bạn đang nhận dữ liệu này từ cơ sở dữ liệu hoặc sổ làm việc Excel. Nếu bạn có các ký tự đặc biệt như La Cañada Flintridge city, trừ khi bạn xuất dữ liệu bằng UTF-8mã hóa, bạn sẽ đưa ra lỗi. La Cañada Flintridge citysẽ trở thành La Ca\xf1ada Flintridge city. Nếu bạn đang sử dụng pandas.read_csvmà không có bất kỳ điều chỉnh nào cho các tham số mặc định, bạn sẽ gặp phải lỗi sau

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

May mắn thay, có một vài giải pháp.

Tùy chọn 1 , sửa lỗi xuất. Hãy chắc chắn để sử dụng UTF-8mã hóa.

Tùy chọn 2 , nếu việc khắc phục sự cố xuất không có sẵn cho bạn và bạn cần sử dụng pandas.read_csv, hãy chắc chắn bao gồm các tham số sau , engine='python'. Theo mặc định, gấu trúc sử dụng engine='C'rất tốt để đọc các tệp lớn, nhưng sẽ sập nếu có bất cứ điều gì bất ngờ xuất hiện. Theo kinh nghiệm của tôi, thiết lập encoding='utf-8'chưa bao giờ sửa lỗi này UnicodeDecodeError. Ngoài ra, bạn không cần sử dụng errors_bad_lines, tuy nhiên, đó vẫn là một tùy chọn nếu bạn THỰC SỰ cần nó.

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

Lựa chọn 3: giải pháp là giải pháp ưa thích của cá nhân tôi. Đọc tệp bằng vani 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)

Hy vọng điều này sẽ giúp mọi người gặp vấn đề này lần đầu tiên.


2

Gặp khó khăn trong một thời gian và nghĩ rằng tôi sẽ đăng câu hỏi này vì đây là kết quả tìm kiếm đầu tiên. Việc thêm encoding="iso-8859-1"thẻ vào gấu trúc read_csvkhông hoạt động, cũng như không có mã hóa nào khác, tiếp tục đưa ra UnicodeDecodeError.

Nếu bạn chuyển một tệp xử lý cho pd.read_csv(),bạn, bạn cần đặt encodingthuộc tính trên tệp đang mở, không phải trong read_csv. Rõ ràng trong nhận thức muộn, nhưng một lỗi tinh tế để theo dõi.


2

Hãy cố gắng thêm

encoding='unicode_escape'

Điều này sẽ giúp. Đã làm cho tôi. Ngoài ra, hãy chắc chắn rằng bạn đang sử dụng tên cột và dấu phân cách chính xác.

Bạn có thể bắt đầu với việc tải chỉ 1000 hàng để tải tệp nhanh chóng.


1

Câu trả lời này dường như là tất cả cho các vấn đề mã hóa CSV. Nếu bạn gặp vấn đề mã hóa lạ với tiêu đề của mình như thế này:

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

Sau đó, bạn có một ký tự đánh dấu thứ tự byte (BOM) ở đầu tệp CSV của bạn. Câu trả lời này giải quyết vấn đề:

Python đọc csv - BOM được nhúng vào khóa đầu tiên

Giải pháp là tải CSV bằng encoding="utf-8-sig":

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

Hy vọng điều này sẽ giúp được ai đó.


1

Tôi đang đăng một bản cập nhật cho chủ đề cũ này. Tôi tìm thấy một giải pháp hiệu quả, nhưng yêu cầu mở từng tệp. Tôi đã mở tệp csv của mình trong LibreOffice, chọn Save As> chỉnh sửa cài đặt bộ lọc. Trong menu thả xuống, tôi chọn mã hóa UTF8. Sau đó, tôi thêm encoding="utf-8-sig"vào data = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig").

Hy vọng điều này sẽ giúp được ai đó.


Nisse, cảm ơn đã chỉnh sửa. Bạn có thể vui lòng giải thích những gì bạn đã thay đổi? Tôi không thấy một sự khác biệt.
tshirtdr1

1

Tôi gặp sự cố khi mở tệp CSV bằng tiếng Trung giản thể được tải xuống từ một ngân hàng trực tuyến, tôi đã thử latin1, tôi đã thử iso-8859-1, tôi đã thử cp1252, tất cả đều vô ích.

Nhưng pd.read_csv("",encoding ='gbk')chỉ đơn giản là làm công việc.


0

Tôi đang sử dụng Jupyter-notebook. Và trong trường hợp của tôi, nó đã hiển thị các tập tin ở định dạng sai. Tùy chọn 'mã hóa' không hoạt động. Vì vậy, tôi lưu csv ở định dạng utf-8, và nó hoạt động.


0

Thử cái này:

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

Có vẻ như nó sẽ chăm sóc mã hóa mà không thể hiện rõ ràng thông qua đối số


0

Kiểm tra mã hóa trước khi bạn chuyển đến gấu trúc. Nó sẽ làm bạn chậm lại, nhưng ...

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

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

Trong trăn 3.7


0

Một vấn đề quan trọng khác mà tôi gặp phải dẫn đến lỗi tương tự là:

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

^ Dòng này dẫn đến cùng một lỗi vì tôi đang đọc một tệp excel bằng read_csv()phương thức. Sử dụng read_excel()để đọc .xlxs


Wow, mọi người khác đang nói về vấn đề mã hóa. Có vẻ như vấn đề của tôi rất đặc biệt.
Mujeeb Ishaque

Đó là bởi vì bạn có một read_excelcon gấu trúc.
Ani Menon

0

Bạn có thể thử điều này.

import csv
import pandas as pd
df = pd.read_csv(filepath,encoding='unicode_escape')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.