UnicodeDecodeError podczas odczytu pliku CSV w Pandach z Pythonem

411

Korzystam z programu, który przetwarza 30 000 podobnych plików. Losowa ich liczba zatrzymuje się i wyświetla ten błąd ...

   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

Źródło / tworzenie tych plików pochodzą z tego samego miejsca. Jak najlepiej to naprawić, aby kontynuować importowanie?

TravisVOX
źródło

Odpowiedzi:

823

read_csvma encodingopcję radzenia sobie z plikami w różnych formatach. Najczęściej używam read_csv('file', encoding = "ISO-8859-1")lub alternatywnie encoding = "utf-8"do czytania i ogólnie utf-8do to_csv.

Możesz także użyć jednej z kilku aliasopcji, takich jak 'latin'zamiast 'ISO-8859-1'(patrz dokumentacja Pythona , a także wiele innych kodowań, które możesz napotkać).

Zobacz odpowiednią dokumentację Pandas , przykłady dokumentacji Pythona dotyczące plików csv i wiele powiązanych pytań tutaj na SO. Dobrym źródłem informacji jest to, co każdy programista powinien wiedzieć o Unicode i zestawach znaków .

Aby wykryć kodowanie (zakładając, że plik zawiera znaki inne niż ascii), możesz użyć enca(patrz strona man ) lub file -i(linux) lub file -I(osx) (patrz strona man ).

Stefan
źródło
7
Ponieważ jest to problem z systemem Windows, cp1252może być lepszym rozwiązaniem iso-8859-1.
tzot
7
Dzięki pd.read_csv('immigration.csv', encoding = "ISO-8859-1", engine='python')działało dla mnie
Mona Jalal
8
Nie zakładaj na ślepo, że pewne kodowanie jest właściwe tylko dlatego, że nie zgłoszono wyjątku. Musisz spojrzeć na ciągi i dowiedzieć się, czy interpretacja ma sens. Na przykład, jeśli zamiast „hors d'œuvre” pojawi się „hors d'½uvre”, prawdopodobnie trzeba przełączyć się z ISO-8859-1 na ISO-8859-15.
Joachim Wagner
6
dla mnie kodowanie było ANSI. Aby to rozgryźć, otworzyłem plik csv, notepada następnie kliknąłem save as, tam pokazuje kodowanie obok przycisku Zapisz.
Vaibhav Vishal,
68

Najprostsze ze wszystkich rozwiązań:

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

Alternatywne rozwiązanie:

  • Otwórz plik csv w edytorze Sublime .
  • Zapisz plik w formacie utf-8.

W wysublimowany kliknij Plik -> Zapisz z kodowaniem -> UTF-8

Następnie możesz normalnie odczytać plik:

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

a inne różne typy kodowania to:

encoding = "cp1252"
encoding = "ISO-8859-1"
Gil Baggio
źródło
11
Pytanie wyjaśnia, że ​​istnieje 30 000 takich plików. Ręczne otwieranie każdego pliku nie byłoby praktyczne.
Keith
4
przynajmniej dla jednego pliku, wydawało mi się, że to działa!
apil.tamang
Silnik C jest wyraźnie bardziej wyrozumiały pod względem tego, co akceptuje. Dla konkretnego pliku CSV, który otwiera się dobrze przy encoding='iso-8859-1'użyciu, zamiast tego engine='python'rzuca _csv.Error: field larger than field limit (131072).
Greg Bacon
1
alternatywne rozwiązanie polegające na użyciu save z kodowaniem było naprawdę pomocne! oto jak używać go do VSCode stackoverflow.com/questions/30082741/…
brownmagik352
20

Pandy pozwalają określić kodowanie, ale nie pozwalają ignorować błędów, aby nie zastępować automatycznie bajtów. Dlatego nie ma jednego rozmiaru pasującego do wszystkich metod, ale różne sposoby w zależności od rzeczywistego przypadku użycia.

  1. Znasz kodowanie i w pliku nie ma błędu kodowania. Świetnie: musisz tylko określić kodowanie:

    file_encoding = 'cp1252'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
  2. Nie chcesz zajmować się kodowaniem pytań, a chcesz tylko załadować ten cholerny plik, bez względu na to, czy niektóre pola tekstowe zawierają śmieci. Ok, musisz tylko użyć Latin1kodowania, ponieważ akceptuje on każdy możliwy bajt jako dane wejściowe (i przekształca go na znak Unicode tego samego kodu):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
  3. Wiesz, że większość pliku jest napisana z określonym kodowaniem, ale zawiera także błędy kodowania. Przykładem świata rzeczywistego jest plik UTF8, który został edytowany za pomocą edytora innego niż utf8 i który zawiera niektóre wiersze z innym kodowaniem. Pandy nie przewidują specjalnego przetwarzania błędów, ale openfunkcja Pythona ma (zakładając, że Python3) i read_csvakceptuje obiekt podobny do pliku. Typowym parametrem błędów, który należy tutaj zastosować, jest 'ignore'po prostu tłumienie obrażających bajtów lub (lepiej IMHO), 'backslashreplace'które zastępują obrażające bajty sekwencją ucieczki ich odwrotnej sekwencji w Pythonie:

    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
źródło
1
Późna odpowiedź, ale ukierunkowana na duplikat pytania ...
Serge Ballesta,
14
with open('filename.csv') as f:
   print(f)

po wykonaniu tego kodu znajdziesz kodowanie pliku „filename.csv”, a następnie wykonaj kod w następujący sposób

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

proszę bardzo

bhavesh
źródło
6

W moim przypadku plik ma USC-2 LE BOMkodowanie, zgodnie z Notepad ++. To jest encoding="utf_16_le"dla pytona.

Mam nadzieję, że pomaga komuś znaleźć odpowiedź nieco szybciej.

Vodyanikov Andrew Anatolevich
źródło
4

W moim przypadku działało to dla Pythona 2.7:

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

A dla Pythona 3 tylko:

data = read_csv(filename, encoding = "ISO-8859-1", low_memory=False) 
Victor Villacorta
źródło
3

Spróbuj podać silnik = „python”. To działało dla mnie, ale wciąż próbuję dowiedzieć się, dlaczego.

df = pd.read_csv(input_file_path,...engine='python')
33 stycznia
źródło
To również działało dla mnie. Podobnie było z kodowaniem = „ISO-8859-1”. To zdecydowanie problem z kodowaniem. Jeśli znak specjalny jest zakodowany w ANSI, taki jak znak elipsy (tj. „...”), i spróbujesz odczytać go w UTF-8, możesz otrzymać błąd. Podsumowując, musisz znać kodowanie, w którym plik został utworzony.
Sean McCarthy
3

Zamieszczam odpowiedź, aby podać zaktualizowane rozwiązanie i wyjaśnienie, dlaczego ten problem może wystąpić. Załóżmy, że otrzymujesz te dane z bazy danych lub skoroszytu programu Excel. Jeśli masz znaki specjalne, np. La Cañada Flintridge cityJeśli nie eksportujesz danych za pomocą UTF-8kodowania, wprowadzisz błędy. La Cañada Flintridge citystanie się La Ca\xf1ada Flintridge city. Jeśli używasz pandas.read_csvbez korekty parametrów domyślnych, trafi się następujący błąd

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

Na szczęście istnieje kilka rozwiązań.

Opcja 1 , napraw eksport. Pamiętaj, aby użyć UTF-8kodowania.

Wariant 2 , jeżeli ustalenie problemu wywozu nie jest dostępna dla Ciebie i trzeba użyć pandas.read_csv, należy pamiętać o następujących paramters, engine='python'. Domyślnie panda używa, engine='C'co jest świetne do czytania dużych, czystych plików, ale zawiesza się, gdy pojawi się coś nieoczekiwanego. Z mojego doświadczenia encoding='utf-8'wynika , że ustawienie nigdy tego nie naprawiło UnicodeDecodeError. Nie musisz też korzystać z tej opcji errors_bad_lines, ale nadal jest to opcja, jeśli NAPRAWDĘ jej potrzebujesz.

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

Opcja 3: rozwiązanie jest moim preferowanym rozwiązaniem osobiście. Przeczytaj plik przy użyciu waniliowego Pythona.

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)

Mam nadzieję, że pomoże to ludziom napotkać ten problem po raz pierwszy.

Jon
źródło
2

Zmagałem się z tym przez chwilę i pomyślałem, że opublikuję to pytanie, ponieważ jest to pierwszy wynik wyszukiwania. Dodanie encoding="iso-8859-1"znacznika do pand read_csvnie działało, podobnie jak żadne inne kodowanie, nadal powodowało błąd UnicodeDecodeError.

Jeśli przekazujesz uchwyt pliku pd.read_csv(),, musisz encodingotworzyć atrybut pliku, a nie w nim read_csv. Oczywiste z perspektywy czasu, ale subtelny błąd do wyśledzenia.

J. Ternent
źródło
2

Spróbuj dodać

encoding='unicode_escape'

To pomoże. Pracował dla mnie. Upewnij się również, że używasz prawidłowego separatora i nazw kolumn.

Możesz rozpocząć od załadowania zaledwie 1000 wierszy, aby szybko załadować plik.

Prakhar Rathi
źródło
1

Ta odpowiedź wydaje się być najważniejsza w przypadku problemów z kodowaniem CSV. Jeśli masz dziwny problem z kodowaniem w nagłówku, taki jak ten:

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

Następnie masz znak bajtu (BOM) na początku pliku CSV. Ta odpowiedź rozwiązuje problem:

Python czyta csv - BOM osadzony w pierwszym kluczu

Rozwiązaniem jest załadowanie pliku CSV z encoding="utf-8-sig":

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

Mam nadzieję, że to komuś pomaga.

nbwoodward
źródło
1

Publikuję aktualizację do tego starego wątku. Znalazłem jedno rozwiązanie, które działało, ale wymaga otwarcia każdego pliku. Otworzyłem plik csv w LibreOffice, wybrałem Zapisz jako> edytuj ustawienia filtra. W menu rozwijanym wybrałem kodowanie UTF8. Następnie dodałem encoding="utf-8-sig"do data = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig").

Mam nadzieję, że to komuś pomoże.

tshirtdr1
źródło
Nisse, dzięki za edycję. Czy możesz wyjaśnić, co zmieniłeś? Nie widzę różnicy.
tshirtdr1
1

Mam problem z otwarciem pliku CSV w języku chińskim uproszczonym pobranym z banku online, próbowałem latin1, próbowałem iso-8859-1, próbowałem cp1252, wszystko bezskutecznie.

Ale pd.read_csv("",encoding ='gbk')po prostu działa.

Luk Aron
źródło
0

Używam notesu Jupyter. W moim przypadku plik był wyświetlany w niewłaściwym formacie. Opcja „kodowania” nie działała. Zapisuję więc csv w formacie utf-8 i działa.

Himanshu Sharma
źródło
0

Spróbuj tego:

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

Wygląda na to, że zajmie się kodowaniem bez wyraźnego wyrażania go za pomocą argumentu

Ke Xu
źródło
0

Sprawdź kodowanie, zanim przejdziesz do pand. Spowolni cię, ale ...

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

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

W python 3.7

DaveP
źródło
0

Innym ważnym problemem, z którym się spotkałem i który spowodował ten sam błąd, było:

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

^ Ten wiersz spowodował ten sam błąd, ponieważ czytam plik programu Excel przy użyciu read_csv()metody. Użyj read_excel()do czytania .xlxs

Mujeeb Ishaque
źródło
Wow, wszyscy inni mówią o problemach z kodowaniem. Wygląda na to, że mój problem był szczególny.
Mujeeb Ishaque
To dlatego, że masz read_excelpandy.
Ani Menon
0

Możesz tego spróbować.

import csv
import pandas as pd
df = pd.read_csv(filepath,encoding='unicode_escape')
Dileep Dominic
źródło