686 Stimmen

UnicodeDecodeError beim Lesen einer CSV-Datei in Pandas

Ich führe ein Programm aus, das 30.000 ähnliche Dateien verarbeitet. Eine zufällige Anzahl von ihnen stoppt und produziert 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 gleichen Ort. Wie kann ich dies am besten korrigieren, um mit dem Import fortzufahren?

1186voto

Stefan Punkte 41649

read_csv nimmt eine Option encoding an, um mit Dateien in verschiedenen Formaten umzugehen. Ich benutze hauptsächlich read_csv('file', encoding = "ISO-8859-1"), oder alternativ encoding = "utf-8" zum Lesen, und im Allgemeinen utf-8 für to_csv.

Sie können auch eine der mehreren alias-Optionen wie 'latin' oder 'cp1252' (Windows) anstelle von 'ISO-8859-1' verwenden (siehe Python-Dokumente, auch für zahlreiche andere Codierungen, die Ihnen begegnen könnten).

Sehen Sie sich die relevanten Pandas-Dokumentationen an, Python-Dokumentationsbeispiele zu CSV-Dateien, und viele verwandte Fragen hier auf SO. Eine gute Hintergrundressource ist Was jeder Entwickler über Unicode und Zeichencodierungen wissen sollte.

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

207voto

Gil Baggio Punkte 10839

Einfachste aller Lösungen:

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

Alternative Lösung:

Sublime Text:

  • Öffnen Sie die CSV-Datei im Sublime-Text-Editor oder in VS Code.
  • Speichern Sie die Datei im UTF-8-Format.
  • In Sublime, klicken Sie auf Datei -> Speichern mit Codierung -> UTF-8

VS Code:

In der unteren Leiste von VSCode sehen Sie das Label UTF-8. Klicken Sie darauf. Ein Popup öffnet sich. Klicken Sie auf Speichern mit Codierung. Sie können jetzt eine neue Codierung für diese Datei wählen.

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"

42voto

Serge Ballesta Punkte 135062

Pandas ermöglicht die Angabe der Codierung, erlaubt jedoch nicht das Ignorieren von Fehlern, um automatisch die fehlerhaften Bytes zu ersetzen. Es gibt also keine Einheitsgröße-für-alles-Methode, sondern verschiedene Möglichkeiten, je nach tatsächlichem Anwendungsfall.

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

    file_encoding = 'cp1252'        # legen Sie file_encoding auf die Dateicodierung fest (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
  2. Sie möchten nicht mit Codierungsfragen belästigt werden und möchten einfach, dass die verdammte Datei geladen wird, egal ob einige Textfelder Müll enthalten. Ok, Sie müssen nur die Latin1-Codierung verwenden, da sie beliebige Bytes als Eingabe akzeptiert (und sie in das Unicode-Zeichen mit dem gleichen Code umwandelt):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
  3. Sie wissen, dass der größte Teil der Datei mit einer bestimmten Codierung geschrieben ist, aber auch Codierungsfehler enthält. Ein reales Beispiel ist eine UTF8-Datei, die mit einem nicht-UTF8-Editor bearbeitet wurde und einige Zeilen mit einer anderen Codierung enthält. Pandas hat keine Möglichkeit für eine spezielle Fehlerverarbeitung, aber die Python open-Funktion hat eine (unter der Annahme von Python3) und read_csv akzeptiert ein Datei-ähnliches Objekt. Die typischen Fehlerparameter, die hier verwendet werden können, sind 'ignore', das einfach die fehlerhaften Bytes unterdrückt, oder (meiner Meinung nach besser) 'backslashreplace', das die fehlerhaften Bytes durch ihre Python-Backslash-Escape-Sequenz ersetzt:

    file_encoding = 'utf8'        # legen Sie file_encoding auf die Dateicodierung fest (utf8, latin1, etc.)
    input_fd = open(input_file_and_path, encoding=file_encoding, errors = 'backslashreplace')
    pd.read_csv(input_fd, ...)

31voto

Fledias weh Punkte 321

Dies ist ein allgemeinerer Skriptansatz für die angegebene Frage.

import pandas as pd

encoding_list = ['ascii', 'big5', 'big5hkscs', 'cp037', 'cp273', 'cp424', 'cp437', 'cp500', 'cp720', 'cp737'
                 , 'cp775', 'cp850', 'cp852', 'cp855', 'cp856', 'cp857', 'cp858', 'cp860', 'cp861', 'cp862'
                 , 'cp863', 'cp864', 'cp865', 'cp866', 'cp869', 'cp874', 'cp875', 'cp932', 'cp949', 'cp950'
                 , 'cp1006', 'cp1026', 'cp1125', 'cp1140', 'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254'
                 , 'cp1255', 'cp1256', 'cp1257', 'cp1258', 'euc_jp', 'euc_jis_2004', 'euc_jisx0213', 'euc_kr'
                 , 'gb2312', 'gbk', 'gb18030', 'hz', 'iso2022_jp', 'iso2022_jp_1', 'iso2022_jp_2'
                 , 'iso2022_jp_2004', 'iso2022_jp_3', 'iso2022_jp_ext', 'iso2022_kr', 'latin_1', 'iso8859_2'
                 , 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', 'iso8859_7', 'iso8859_8', 'iso8859_9'
                 , 'iso8859_10', 'iso8859_11', 'iso8859_13', 'iso8859_14', 'iso8859_15', 'iso8859_16', 'johab'
                 , 'koi8_r', 'koi8_t', 'koi8_u', 'kz1048', 'mac_cyrillic', 'mac_greek', 'mac_iceland', 'mac_latin2'
                 , 'mac_roman', 'mac_turkish', 'ptcp154', 'shift_jis', 'shift_jis_2004', 'shift_jisx0213', 'utf_32'
                 , 'utf_32_be', 'utf_32_le', 'utf_16', 'utf_16_be', 'utf_16_le', 'utf_7', 'utf_8', 'utf_8_sig']

for encoding in encoding_list:
    worked = True
    try:
        df = pd.read_csv(path, encoding=encoding, nrows=5)
    except:
        worked = False
    if worked:
        print(encoding, ':\n', df.head())

Man beginnt mit allen standardmäßigen Encodings, die für die Python-Version verfügbar sind (in diesem Fall 3.7 Python 3.7 Standard Encodings). Eine verwendbare Python-Liste der Standardencodings für die verschiedenen Python-Versionen findet sich hier: Hilfreiche Antwort bei Stack Overflow

Man versucht jedes Encoding an einem kleinen Ausschnitt der Daten; nur das funktionierende Encoding wird ausgegeben. Das Ergebnis ist sofort ersichtlich. Dieser Output adressiert auch das Problem, dass ein Encoding wie 'latin1', das ohne Fehler durchläuft, nicht unbedingt das gewünschte Ergebnis liefert.

Für den vorliegenden Fall würde ich diesen spezifischen Ansatz für problematische CSV-Dateien ausprobieren und dann möglicherweise versuchen, das gefundene funktionierende Encoding für alle anderen zu verwenden.

25voto

Prakhar Rathi Punkte 919

Bitte versuchen Sie hinzuzufügen

import pandas as pd
df = pd.read_csv('file.csv', encoding='unicode_escape')

Dies wird helfen. Hat bei mir funktioniert. Stellen Sie außerdem sicher, dass Sie das richtige Trennzeichen und Spaltennamen verwenden.

Sie können damit beginnen, nur 1000 Zeilen zu laden, um die Datei schnell zu laden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X