UnicodeDecodeError beim Lesen einer CSV-Datei in Pandas

Lesezeit: 7 Minuten

Benutzeravatar von TravisVOX
TravisVOX

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 stammen alle vom selben Ort. Was ist der beste Weg, dies zu korrigieren, um mit dem Import fortzufahren?

Benutzeravatar von Stefan
Stefan

read_csv dauert ein encoding Option zum Umgang mit Dateien in verschiedenen Formaten. verwende ich meistens read_csv('file', encoding = "ISO-8859-1")oder alternativ encoding = "utf-8" zum Lesen und allgemein utf-8 für to_csv.

Sie können auch einen von mehreren verwenden alias Optionen wie 'latin' oder 'cp1252' (Windows) statt 'ISO-8859-1' (sehen Python-Dokumenteauch für zahlreiche andere Kodierungen, denen Sie begegnen können).

Sehen relevante Pandas-Dokumentation,
Python-Dokumentationsbeispiele zu CSV-Dateien, und viele verwandte Fragen hier auf 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 verwenden enca (sehen Manpage) oder file -i (Linux) bzw file -I (osx) (vgl Manpage).

  • @Ben Hier ist eine gute Ressource Was jeder Entwickler über Unicode und Zeichensätze wissen sollte

    – Stefan

    14. Juni 2019 um 13:53 Uhr


  • ISO-8859-1 hat die einzigartige Eigenschaft unter den Python-Codierungen, dass es absolut alle Binärdaten lesen kann, ohne einen Fehler auszulösen. Sehr oft probieren Anfänger verschiedene Kodierungen aus, ohne sich die resultierenden Daten wirklich anzusehen, und fragen sich dann, warum ihre Ergebnisse Müll sind, wenn sie die falsche ausgewählt haben.

    – Dreier

    6. April 2022 um 17:03 Uhr


  • @tripleee es gibt keine “Python-Codierungen” (es sei denn, Sie zählen Dinge wie die Implementierung von ROT-13 als “Codierung” in Pythons System); ISO-8859-1 ist ein international anerkannter Standard (daher ISO), der unzählige Male in unzähligen Umgebungen implementiert wurde. Zehn der sechzehn ISO-8859-Codierungen können beliebige Binärdateien verarbeiten, ebenso wie mehrere historische DOS-Codepages, ältere Macintosh-Textcodierungen und einige andere. ISO-8859-1 tut haben jedoch die (notwendigerweise) einzigartige Eigenschaft, dass diese Bytes den ersten 256 Unicode-Codepunkten in der Reihenfolge zugeordnet werden.

    – Karl Knechtel

    18. August 2022 um 1:41 Uhr

  • Sicher, ich meinte unter den Zeichenkodierungen, die Python unterstützt.

    – Dreier

    18. August 2022 um 4:38 Uhr

Benutzeravatar von Gil Baggio
Gil Baggio

Einfachste aller Lösungen:

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

Alternative Lösung:

Erhabener Text:

  • Öffnen Sie die csv-Datei in Erhabener Texteditor oder VS-Code.
  • Speichern Sie die Datei im utf-8-Format.
  • Klicken Sie in Sublime auf Datei -> Mit Codierung speichern -> UTF-8

VS-Code:

In der unteren Leiste von VSCode sehen Sie die Bezeichnung UTF-8. Klick es. Ein Popup öffnet sich. Klicken Sie auf Mit Kodierung speichern. Sie können jetzt eine neue Kodierung für diese Datei auswählen.

Dann könnten 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"

Pandas erlaubt die Angabe der Codierung, erlaubt jedoch nicht, Fehler zu ignorieren, um die anstößigen Bytes nicht automatisch zu ersetzen. Es gibt also keine eine Grösse passt allen Methode, aber je nach Anwendungsfall auf unterschiedliche Weise.

  1. Sie kennen die Kodierung und es gibt keinen Kodierungsfehler 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 Kodierungsfragen herumärgern und nur diese verdammte Datei laden, egal ob einige Textfelder Müll enthalten. Ok, Sie müssen nur verwenden Latin1 Codierung, weil es 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 sie enthält auch Codierungsfehler. 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 hat keine spezielle Fehlerbehandlung vorgesehen, sondern Python open Funktion hat (unter der Annahme von Python3) und read_csv akzeptiert eine Datei wie ein Objekt. Typische Fehlerparameter sind hier zu verwenden 'ignore' was nur die anstößigen Bytes unterdrückt oder (IMHO besser) 'backslashreplace' die die anstößigen Bytes durch die Backslash-Escape-Sequenz ihrer Python ersetzt:

    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, ...)
    

Benutzeravatar von Fledias weh
Fledias weh

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 Standardcodierungen, die für die Python-Version verfügbar sind (in diesem Fall 3.7 Python 3.7-Standardkodierungen). Eine verwendbare Python-Liste der Standardcodierungen für die verschiedenen Python-Versionen finden Sie hier: Hilfreiche Antwort auf den Stapelüberlauf

Probieren Sie jede Codierung an einem kleinen Teil der Daten aus. nur die Arbeitscodierung drucken. Die Ausgabe ist direkt ersichtlich. Diese Ausgabe adressiert auch das Problem, dass eine Kodierung wie ‘latin1’, die ohne Fehler durchläuft, nicht unbedingt das gewünschte Ergebnis liefert.

Im Falle der Frage würde ich diesen Ansatz spezifisch für problematisch versuchen CSV Datei und versuchen Sie dann vielleicht, die gefundene funktionierende Codierung für alle anderen zu verwenden.

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

Nachdem Sie diesen Code ausgeführt haben, finden Sie die Codierung von ‚filename.csv‘ und führen dann den Code wie folgt aus

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

da gehst du

Bitte versuchen Sie es hinzuzufügen

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

Das wird helfen. Hat für mich funktioniert. 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.

Benutzeravatar von ah bon
ah gut

Versuchen Sie, die Codierung zu ändern. In meinem Fall, encoding = "utf-16" hat funktioniert.

df = pd.read_csv("file.csv",encoding='utf-16')

1449050cookie-checkUnicodeDecodeError beim Lesen einer CSV-Datei in Pandas

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy