UnicodeDecodeError beim Lesen einer CSV-Datei in Pandas mit Python

411

Ich führe ein Programm aus, das 30.000 ähnliche Dateien verarbeitet. Eine zufällige Anzahl von ihnen stoppt und erzeugt diesen Fehler ...

   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

Die Quelle / Erstellung dieser Dateien stammt alle vom selben Ort. Wie kann dies am besten korrigiert werden, um mit dem Import fortzufahren?

TravisVOX
quelle

Antworten:

820

read_csvnimmt eine encodingOption mit Dateien in verschiedenen Formaten zu behandeln. Ich benutze meistens read_csv('file', encoding = "ISO-8859-1")oder alternativ encoding = "utf-8"zum Lesen und allgemein utf-8für to_csv.

Sie können auch eine von mehreren aliasOptionen wie 'latin'anstelle von verwenden 'ISO-8859-1'(siehe Python-Dokumente , auch für zahlreiche andere Codierungen, auf die Sie möglicherweise stoßen).

Siehe relevante Pandas-Dokumentation , Beispiele für Python-Dokumente zu CSV-Dateien und viele verwandte Fragen hier zu SO. Eine gute Hintergrundressource ist, was jeder Entwickler über Unicode- und Zeichensätze wissen sollte .

Um die Codierung zu erkennen (vorausgesetzt, die Datei enthält Nicht-ASCII-Zeichen), können Sie enca(siehe Manpage ) oder file -i(Linux) oder file -I(osx) (siehe Manpage ) verwenden.

Stefan
quelle
7
Da es sich um ein Windows-Problem handelt, ist dies cp1252möglicherweise vorzuziehen iso-8859-1.
Zot
7
Vielen Dank pd.read_csv('immigration.csv', encoding = "ISO-8859-1", engine='python')für mich gearbeitet
Mona Jalal
8
Gehen Sie nicht blind davon aus, dass eine bestimmte Codierung die richtige ist, nur weil keine Ausnahme ausgelöst wird. Sie müssen sich die Zeichenfolgen ansehen und herausfinden, ob die Interpretation sinnvoll ist. Wenn Sie beispielsweise "Vorspeise" anstelle von "Vorspeise" erhalten, müssen Sie wahrscheinlich von ISO-8859-1 zu ISO-8859-15 wechseln.
Joachim Wagner
5
für mich war die Kodierung ANSI. Um es herauszufinden, habe ich die CSV geöffnet und notepaddann auf geklickt save as. Dort wird die Codierung neben der Schaltfläche Speichern angezeigt.
Vaibhav Vishal
4
@ Ben Hier ist eine gute Ressource Was jeder Entwickler über Unicode und Zeichensätze wissen sollte
Stefan
68

Einfachste aller Lösungen:

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

Alternative Lösung:

  • Öffnen Sie die CSV-Datei im Sublime-Texteditor .
  • Speichern Sie die Datei im utf-8-Format.

Klicken Sie in sublime auf Datei -> Mit Codierung speichern -> UTF-8

Dann können Sie Ihre Datei wie gewohnt lesen:

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

und die anderen verschiedenen Codierungstypen sind:

encoding = "cp1252"
encoding = "ISO-8859-1"
Gil Baggio
quelle
10
Die Frage erklärt, dass es 30.000 solcher Dateien gibt. Das manuelle Öffnen jeder Datei wäre nicht praktikabel.
Keith
4
Nun, zumindest für eine Datei schien dies für mich zu funktionieren!
apil.tamang
Der C-Motor verzeiht offenbar mehr, was er akzeptiert. encoding='iso-8859-1'Verwenden Sie für eine bestimmte CSV-Datei, die sich gut mit öffnen lässt, stattdessen engine='python'Würfe _csv.Error: field larger than field limit (131072).
Greg Bacon
1
Die alternative Lösung zum Speichern mit Codierung war sehr hilfreich! So verwenden Sie es für VSCode stackoverflow.com/questions/30082741/…
brownmagik352
20

Pandas erlaubt die Angabe der Codierung, erlaubt jedoch nicht das Ignorieren von Fehlern, um die fehlerhaften Bytes nicht automatisch zu ersetzen. Es gibt also keine Einheitsgröße für alle Methoden, sondern je nach Anwendungsfall unterschiedliche Methoden.

  1. Sie kennen die Codierung und es gibt keinen Codierungsfehler in der Datei. Großartig: Sie müssen nur die Codierung angeben:

    file_encoding = 'cp1252'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
  2. Sie möchten sich nicht mit Codierungsfragen beschäftigen und möchten nur, dass diese verdammte Datei geladen wird, egal ob einige Textfelder Müll enthalten. Ok, Sie müssen nur die Latin1Codierung verwenden , da sie jedes mögliche Byte als Eingabe akzeptiert (und es in das Unicode-Zeichen desselben Codes konvertiert):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
  3. Sie wissen, dass der größte Teil der Datei mit einer bestimmten Codierung geschrieben wurde, aber auch Codierungsfehler enthält. Ein Beispiel aus der Praxis ist eine UTF8-Datei, die mit einem Nicht-Utf8-Editor bearbeitet wurde und einige Zeilen mit einer anderen Codierung enthält. Pandas opensieht keine spezielle Fehlerverarbeitung vor, die Python- Funktion jedoch (unter der Annahme von Python3) und read_csvakzeptiert ein dateiähnliches Objekt. Typische Fehlerparameter, die hier verwendet werden, sind, 'ignore'die nur die beleidigenden Bytes unterdrücken oder (IMHO besser) 'backslashreplace'die beleidigenden Bytes durch die umgekehrte Escape-Sequenz ihres Pythons ersetzen:

    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
quelle
1
Späte Antwort, aber auf eine doppelte Frage ausgerichtet ...
Serge Ballesta
14
with open('filename.csv') as f:
   print(f)

Nach dem Ausführen dieses Codes finden Sie die Codierung von 'filename.csv' und führen den Code wie folgt aus

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

los geht's

Bhavesh
quelle
6

In meinem Fall hat eine Datei USC-2 LE BOMlaut Notepad ++ eine Codierung. Es ist encoding="utf_16_le"für Python.

Hoffe, es hilft, eine Antwort für jemanden etwas schneller zu finden.

Vodyanikov Andrew Anatolevich
quelle
4

In meinem Fall funktionierte dies für Python 2.7:

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

Und nur für Python 3:

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

Versuchen Sie, die Engine = 'Python' anzugeben. Es hat bei mir funktioniert, aber ich versuche immer noch herauszufinden, warum.

df = pd.read_csv(input_file_path,...engine='python')
Jan33
quelle
Das hat auch bei mir funktioniert. Codierung = "ISO-8859-1" auch. Es ist definitiv ein Codierungsproblem. Wenn ein Sonderzeichen in ANSI codiert ist, z. B. ein Ellipsenzeichen (dh "..."), und Sie versuchen, es in UTF-8 zu lesen, wird möglicherweise eine Fehlermeldung angezeigt. Unter dem Strich müssen Sie die Codierung kennen, mit der die Datei erstellt wurde.
Sean McCarthy
3

Ich poste eine Antwort, um eine aktualisierte Lösung und Erklärung zu liefern, warum dieses Problem auftreten kann. Angenommen, Sie erhalten diese Daten aus einer Datenbank oder einer Excel-Arbeitsmappe. Wenn Sie Sonderzeichen wie haben La Cañada Flintridge city, werden Sie UTF-8Fehler einführen , es sei denn, Sie exportieren die Daten mithilfe der Codierung. La Cañada Flintridge citywird werden La Ca\xf1ada Flintridge city. Wenn Sie pandas.read_csvohne Anpassung der Standardparameter verwenden, wird der folgende Fehler angezeigt

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

Zum Glück gibt es einige Lösungen.

Option 1 , korrigieren Sie den Export. Stellen Sie sicher, dass Sie die UTF-8Codierung verwenden.

Option 2 : Wenn Ihnen pandas.read_csvdas Beheben des Exportproblems nicht zur Verfügung steht und Sie es verwenden müssen , müssen Sie die folgenden Parameter einschließen : engine='python'. Standardmäßig verwendet pandas engine='C'die Funktion zum Lesen großer, sauberer Dateien, stürzt jedoch ab, wenn unerwartete Ereignisse auftreten. Nach meiner Erfahrung hat die Einstellung dies encoding='utf-8'nie behoben UnicodeDecodeError. Sie müssen es jedoch nicht verwenden errors_bad_lines, dies ist jedoch immer noch eine Option, wenn Sie es WIRKLICH benötigen.

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

Option 3: Lösung ist meine bevorzugte persönliche Lösung. Lesen Sie die Datei mit 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)

Ich hoffe, dies hilft Menschen, die zum ersten Mal auf dieses Problem stoßen.

Jon
quelle
2

Ich hatte eine Weile damit zu kämpfen und dachte, ich würde diese Frage posten, da es das erste Suchergebnis ist. Das Hinzufügen des encoding="iso-8859-1"Tags zu Pandas read_csvfunktionierte nicht und auch keine andere Codierung ergab weiterhin einen UnicodeDecodeError.

Wenn Sie ein Dateihandle übergeben, müssen pd.read_csv(),Sie das encodingAttribut in die geöffnete Datei einfügen, nicht in read_csv. Im Nachhinein offensichtlich, aber ein subtiler Fehler beim Aufspüren.

J. Ternent
quelle
1

Diese Antwort scheint das Allheilmittel für CSV-Codierungsprobleme zu sein. Wenn Sie ein seltsames Codierungsproblem mit Ihrem Header wie folgt haben:

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

Dann haben Sie am Anfang Ihrer CSV-Datei ein Stücklistenzeichen (Byte Order Mark). Diese Antwort behebt das Problem:

Python liest csv - Stückliste, die in den ersten Schlüssel eingebettet ist

Die Lösung besteht darin, die CSV zu laden mit encoding="utf-8-sig":

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

Hoffentlich hilft das jemandem.

nbwoodward
quelle
1

Ich poste ein Update für diesen alten Thread. Ich habe eine Lösung gefunden, die funktioniert, aber das Öffnen jeder Datei erfordert. Ich habe meine CSV-Datei in LibreOffice geöffnet und Speichern unter> Filtereinstellungen bearbeiten gewählt. Im Dropdown-Menü habe ich die UTF8-Codierung ausgewählt. Dann habe ich encoding="utf-8-sig"auf die data = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig").

Hoffe das hilft jemandem.

tshirtdr1
quelle
Nisse, danke für die Bearbeitung. Können Sie bitte erklären, was Sie geändert haben? Ich sehe keinen Unterschied.
tshirtdr1
1

Ich habe Probleme beim Öffnen einer CSV-Datei in vereinfachtem Chinesisch, die von einer Online-Bank heruntergeladen wurde. Ich habe es versucht latin1, ich habe es versucht iso-8859-1, ich habe es versucht cp1252, alles ohne Erfolg.

Aber macht pd.read_csv("",encoding ='gbk')einfach die Arbeit.

Luk Aron
quelle
1

Bitte versuchen Sie hinzuzufügen

encoding='unicode_escape'

Das wird helfen. Hat für mich gearbeitet. Stellen Sie außerdem sicher, dass Sie die richtigen Trennzeichen und Spaltennamen verwenden.

Sie können mit dem Laden von nur 1000 Zeilen beginnen, um die Datei schnell zu laden.

Prakhar Rathi
quelle
0

Ich benutze Jupyter-Notebook. In meinem Fall wurde die Datei im falschen Format angezeigt. Die Option "Codierung" funktionierte nicht. Also speichere ich die CSV im Utf-8-Format und es funktioniert.

Himanshu Sharma
quelle
0

Versuche dies:

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

Es sieht so aus, als würde es sich um die Codierung kümmern, ohne sie explizit durch Argumente auszudrücken

Ke Xu
quelle
0

Überprüfen Sie die Kodierung, bevor Sie zu Pandas übergehen. Es wird dich verlangsamen, aber ...

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

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

In Python 3.7

DaveP
quelle
0

Ein weiteres wichtiges Problem, mit dem ich konfrontiert war und das zu demselben Fehler führte, war:

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

^ Diese Zeile führte zu demselben Fehler, da ich eine Excel-Datei mit der read_csv()Methode lese . Verwenden Sie read_excel()zum Lesen .xlxs

Mujeeb Ishaque
quelle
Wow, alle anderen reden über Codierungsprobleme. Sieht so aus, als wäre mein Problem eigenartig.
Mujeeb Ishaque
Es ist, weil Sie eine read_excelin Pandas haben.
Ani Menon