UnicodeDecodeError al leer un archivo CSV en Pandas con Python


Estoy ejecutando un programa que está procesando 30.000 archivos similares. Un número aleatorio de ellos se detiene y produce este error...

   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

La fuente/creación de estos archivos todos vienen del mismo lugar. ¿Cuál es la mejor manera de corregir esto para proceder con la importación?

Author: Stefan, 2013-08-11

4 answers

read_csv toma una opción encoding para tratar archivos en diferentes formatos. Utilizo principalmente read_csv('file', encoding = "ISO-8859-1"), o alternativamente encoding = "utf-8" para leer, y generalmente utf-8 para to_csv.

También puede usar el alias 'latin1' en lugar de 'ISO-8859-1'.

Véase documentación pertinente sobre Pandas , ejemplos de documentos de python en archivos csv, y muchas preguntas relacionadas aquí sobre SO.

 400
Author: Stefan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-31 22:21:39

La más simple de todas las soluciones:

  • Abra el archivo csv en Sublime text editor.
  • Guarde el archivo en formato utf-8.

En sublime, Haga clic en Archivo - > Guardar con codificación - > UTF-8

Entonces, puede leer su archivo como de costumbre:

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

EDITAR 1:

Si hay muchos archivos, entonces puede omitir el paso sublime.

Simplemente lea el archivo usando

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

Y los otros tipos de codificación diferentes son:

encoding = "cp1252"
encoding = "ISO-8859-1"
 14
Author: Gil Baggio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-09 04:49:10

Pandas permite especificar la codificación, pero no permite ignorar errores para no reemplazar automáticamente los bytes ofensivos. Por lo tanto, no hay un método de un solo tamaño para todos, sino diferentes formas dependiendo del caso de uso real.

  1. Conoce la codificación y no hay ningún error de codificación en el archivo. Genial: solo tienes que especificar la codificación:

    file_encoding = 'cp1252'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
    
  2. No quieres que te molesten las preguntas de codificación, y solo quieres que ese maldito archivo se cargue, no importa si algunos campos de texto contienen basura. Ok, solo tienes que usar la codificación Latin1 porque acepta cualquier byte posible como entrada (y lo convierte al carácter unicode del mismo código):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
    
  3. Usted sabe que la mayor parte del archivo está escrito con una codificación específica, pero también contiene errores de codificación. Un ejemplo del mundo real es un archivo UTF8 que ha sido editado con un editor no utf8 y que contiene algunas líneas con una codificación diferente. Pandas no tiene ninguna provisión para un procesamiento de errores especiales, pero la función Python open tiene (asumiendo Python3), y read_csv acepta un archivo como objeto. El parámetro de errores típicos a usar aquí son 'ignore' que simplemente suprime los bytes ofensivos o (mejor en mi humilde opinión) 'backslashreplace' que reemplaza los bytes ofensivos por la secuencia de escape con barra invertida de Python:

    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, ...)
    
 3
Author: Serge Ballesta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-09 09:42:15

Luché con esto un tiempo y pensé en publicar sobre esta pregunta, ya que es el primer resultado de búsqueda. Agregar la etiqueta encoding='iso-8859-1" a pandas read_csv no funcionó, ni ninguna otra codificación, siguió dando un UnicodeDecodeError.

Si está pasando un controlador de archivo a pd.read_csv (), necesita poner el atributo encoding= en el archivo abierto, no en read_csv. Obvio en retrospectiva, pero un error sutil para rastrear.

 1
Author: J. Ternent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-13 17:12:35