UnicodeDecodeError saat membaca file CSV di Pandas dengan Python

411

Saya menjalankan program yang sedang memproses 30.000 file serupa. Sejumlah acak dari mereka berhenti dan menghasilkan kesalahan ini ...

   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

Sumber / pembuatan semua file ini berasal dari tempat yang sama. Apa cara terbaik untuk memperbaikinya untuk melanjutkan impor?

TravisVOX
sumber

Jawaban:

823

read_csvmengambil encodingopsi untuk menangani file dalam format yang berbeda. Saya kebanyakan menggunakan read_csv('file', encoding = "ISO-8859-1"), atau sebagai alternatif encoding = "utf-8"untuk membaca, dan umumnya utf-8untuk to_csv.

Anda juga dapat menggunakan salah satu dari beberapa aliasopsi seperti 'latin'sebagai ganti 'ISO-8859-1'(lihat python docs , juga untuk banyak penyandian lain yang mungkin Anda temui).

Lihat dokumentasi Pandas yang relevan , contoh dokumen python pada file csv , dan banyak pertanyaan terkait di sini di SO. Sumber latar belakang yang baik adalah Apa yang harus diketahui setiap pengembang tentang unicode dan set karakter .

Untuk mendeteksi penyandian (dengan asumsi file berisi karakter non-ascii), Anda dapat menggunakan enca(lihat halaman manual ) atau file -i(linux) atau file -I(osx) (lihat halaman manual ).

Stefan
sumber
7
Karena ini adalah masalah Windows, cp1252mungkin lebih disukai iso-8859-1.
tzot
7
Terima kasih pd.read_csv('immigration.csv', encoding = "ISO-8859-1", engine='python')berhasil untuk saya
Mona Jalal
8
Jangan secara membabi buta menganggap pengkodean tertentu adalah yang benar hanya karena tidak ada pengecualian yang dilemparkan. Anda perlu melihat senar dan mencari tahu apakah interpretasinya masuk akal. Misalnya, jika Anda mendapatkan "hors d'½uvre" alih-alih "hors d'œuvre" Anda mungkin harus beralih dari ISO-8859-1 ke ISO-8859-15.
Joachim Wagner
6
bagi saya pengkodean adalah ANSI. Untuk mengetahuinya, saya membuka csv di notepadkemudian klik save as, di sana itu menunjukkan pengkodean di sebelah tombol simpan.
Vaibhav Vishal
69

Solusi termudah:

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

Solusi Alternatif:

  • Buka file csv dalam editor teks Sublime .
  • Simpan file dalam format utf-8.

Dalam luhur, Klik File -> Simpan dengan encoding -> UTF-8

Kemudian, Anda dapat membaca file Anda seperti biasa:

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

dan jenis pengkodean berbeda lainnya adalah:

encoding = "cp1252"
encoding = "ISO-8859-1"
Gil Baggio
sumber
11
Pertanyaannya menjelaskan bahwa ada 30.000 file seperti itu. Membuka setiap file secara manual tidak akan praktis.
Keith
4
setidaknya untuk satu file, ini sepertinya bekerja untuk saya!
apil.tamang
Mesin C jelas lebih pemaaf dalam apa yang diterimanya. Untuk file CSV tertentu yang terbuka dengan baik encoding='iso-8859-1', gunakan bukan engine='python'melempar _csv.Error: field larger than field limit (131072).
Greg Bacon
1
solusi alternatif untuk menggunakan save dengan encoding sangat membantu! inilah cara menggunakannya untuk VSCode stackoverflow.com/questions/30082741/…
brownmagik352
20

Panda memungkinkan untuk menentukan penyandian, tetapi tidak memungkinkan untuk mengabaikan kesalahan untuk tidak secara otomatis mengganti byte yang menyinggung. Jadi tidak ada satu ukuran yang cocok untuk semua metode tetapi cara yang berbeda tergantung pada kasus penggunaan yang sebenarnya.

  1. Anda tahu penyandian, dan tidak ada kesalahan penyandian dalam file. Hebat: Anda baru saja menentukan pengkodean:

    file_encoding = 'cp1252'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
  2. Anda tidak ingin diganggu dengan pertanyaan penyandian, dan hanya ingin file sialan itu dimuat, tidak masalah jika beberapa bidang teks mengandung sampah. Oke, Anda hanya perlu menggunakan Latin1pengodean karena ia menerima byte apa pun yang mungkin sebagai input (dan mengubahnya menjadi karakter unicode dari kode yang sama):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
  3. Anda tahu bahwa sebagian besar file ditulis dengan penyandian khusus, tetapi juga berisi kesalahan penyandian. Contoh dunia nyata adalah file UTF8 yang telah diedit dengan editor non utf8 dan yang berisi beberapa baris dengan penyandian berbeda. Panda tidak memiliki ketentuan untuk pemrosesan kesalahan khusus, tetapi openfungsi Python telah (dengan asumsi Python3), dan read_csvmenerima file seperti objek. Parameter kesalahan umum untuk digunakan di sini adalah 'ignore'yang hanya menekan byte yang menyinggung atau (IMHO lebih baik) 'backslashreplace'yang menggantikan byte yang menyinggung oleh urutan melarikan diri backslashed Python mereka:

    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, ...)
Serge Ballesta
sumber
1
Jawaban terlambat, tetapi ditargetkan pada pertanyaan rangkap ...
Serge Ballesta
14
with open('filename.csv') as f:
   print(f)

setelah mengeksekusi kode ini Anda akan menemukan pengkodean 'filename.csv' kemudian jalankan kode sebagai berikut

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

ini dia

Bhavesh
sumber
6

Dalam kasus saya, file memiliki USC-2 LE BOMencoding, menurut Notepad ++. Ini encoding="utf_16_le"untuk python.

Semoga bermanfaat untuk menemukan jawaban yang sedikit lebih cepat bagi seseorang.

Vodyanikov Andrew Anatolevich
sumber
4

Dalam kasus saya ini berfungsi untuk python 2.7:

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

Dan untuk python 3, hanya:

data = read_csv(filename, encoding = "ISO-8859-1", low_memory=False) 
Victor Villacorta
sumber
3

Coba tentukan engine = 'python'. Itu berhasil untuk saya, tetapi saya masih mencoba mencari tahu mengapa.

df = pd.read_csv(input_file_path,...engine='python')
Jan33
sumber
Ini juga bekerja untuk saya. Begitu juga penyandian = "ISO-8859-1". Ini jelas merupakan masalah penyandian. Jika karakter khusus dikodekan dalam ANSI, seperti karakter elips (yaitu "..."), dan Anda mencoba membacanya di UTF-8, Anda mungkin mendapatkan kesalahan. Intinya adalah Anda harus tahu pengkodean file dibuat dengan.
Sean McCarthy
3

Saya memposting jawaban untuk memberikan solusi dan penjelasan terbaru tentang mengapa masalah ini dapat terjadi. Katakanlah Anda mendapatkan data ini dari database atau buku kerja Excel. Jika Anda memiliki karakter khusus seperti La Cañada Flintridge city, baik kecuali jika Anda mengekspor data menggunakan UTF-8pengkodean, Anda akan memperkenalkan kesalahan. La Cañada Flintridge cityakan menjadi La Ca\xf1ada Flintridge city. Jika Anda menggunakan pandas.read_csvtanpa penyesuaian pada parameter default, Anda akan menemukan kesalahan berikut

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

Untungnya, ada beberapa solusi.

Opsi 1 , perbaiki ekspor. Pastikan untuk menggunakan UTF-8pengodean.

Opsi 2 , jika memperbaiki masalah ekspor tidak tersedia untuk Anda, dan Anda perlu menggunakan pandas.read_csv, pastikan untuk menyertakan parameter berikut engine='python',. Secara default, panda menggunakan engine='C'yang bagus untuk membaca file besar yang bersih, tetapi akan macet jika sesuatu yang tidak terduga muncul. Dalam pengalaman saya, pengaturan encoding='utf-8'tidak pernah memperbaiki ini UnicodeDecodeError. Selain itu, Anda tidak perlu menggunakan errors_bad_lines, namun, itu masih merupakan opsi jika Anda BENAR - BENAR membutuhkannya.

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

Opsi 3: solusi adalah solusi pilihan saya secara pribadi. Baca file menggunakan 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)

Semoga ini bisa membantu orang menghadapi masalah ini untuk pertama kalinya.

Jon
sumber
2

Berjuang dengan ini sebentar dan berpikir saya akan memposting pertanyaan ini karena ini adalah hasil pencarian pertama. Menambahkan encoding="iso-8859-1"tag ke panda read_csvtidak berfungsi, juga penyandian lainnya, terus memberikan UnicodeDecodeError.

Jika Anda memberikan pegangan file ke pd.read_csv(),Anda harus menempatkan encodingatribut pada file terbuka, bukan di read_csv. Jelas di belakang, tetapi kesalahan halus untuk melacak.

J. Ternent
sumber
2

Silakan coba tambahkan

encoding='unicode_escape'

Ini akan membantu. Bekerja untukku. Pastikan juga Anda menggunakan pembatas dan nama kolom yang benar.

Anda dapat mulai dengan memuat hanya 1000 baris untuk memuat file dengan cepat.

Prakhar Rathi
sumber
1

Jawaban ini tampaknya cocok untuk semua masalah pengkodean CSV. Jika Anda mendapatkan masalah penyandian yang aneh dengan tajuk Anda seperti ini:

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

Kemudian Anda memiliki karakter tanda pesanan byte (BOM) di awal file CSV Anda. Jawaban ini mengatasi masalah:

Python read csv - BOM disematkan ke kunci pertama

Solusinya adalah memuat CSV dengan encoding="utf-8-sig":

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

Semoga ini bisa membantu seseorang.

nbwoodward
sumber
1

Saya memposting pembaruan ke utas lama ini. Saya menemukan satu solusi yang berhasil, tetapi membutuhkan pembukaan setiap file. Saya membuka file csv saya di LibreOffice, memilih Simpan Sebagai> edit pengaturan filter. Dalam menu drop-down saya memilih pengkodean UTF8. Lalu saya menambahkan encoding="utf-8-sig"kedata = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig") .

Semoga ini bisa membantu seseorang.

tshirtdr1
sumber
Nisse, terima kasih atas hasil editnya. Bisakah Anda jelaskan apa yang Anda ubah? Saya tidak melihat perbedaan.
tshirtdr1
1

Saya kesulitan membuka file CSV dalam bahasa Cina sederhana yang diunduh dari bank online, saya sudah mencoba latin1, sudah mencoba iso-8859-1, sudah mencobacp1252 , semuanya sia-sia.

Tetapi pd.read_csv("",encoding ='gbk')cukup berhasil.

Luk Aron
sumber
0

Saya menggunakan Jupyter-notebook. Dan dalam kasus saya, itu menunjukkan file dalam format yang salah. Opsi 'encoding' tidak berfungsi. Jadi saya menyimpan csv dalam format utf-8, dan berfungsi.

Himanshu Sharma
sumber
0

Coba ini:

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

Sepertinya itu akan menangani pengodean tanpa secara eksplisit mengungkapkannya melalui argumen

Ke Xu
sumber
0

Periksa pengodean sebelum Anda beralih ke panda. Ini akan memperlambat Anda, tetapi ...

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

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

Dalam python 3.7

DaveP
sumber
0

Masalah penting lain yang saya hadapi yang menghasilkan kesalahan yang sama adalah:

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

^ Baris ini menghasilkan kesalahan yang sama karena saya membaca file excel menggunakan read_csv()metode. Gunakan read_excel()untuk membaca .xlxs

Mujeeb Ishaque
sumber
Wow, semua orang berbicara tentang masalah penyandian. Sepertinya masalah saya aneh.
Mujeeb Ishaque
Itu karena Anda memiliki read_excelpanda.
Ani Menon
0

Anda bisa mencoba ini.

import csv
import pandas as pd
df = pd.read_csv(filepath,encoding='unicode_escape')
Dileep Dominic
sumber