UnicodeDecodeError al leer el archivo CSV en Pandas con Python

412

Estoy ejecutando un programa que procesa 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 provienen del mismo lugar. ¿Cuál es la mejor manera de corregir esto para continuar con la importación?

TravisVOX
fuente

Respuestas:

824

read_csvtoma una encodingopción para manejar archivos en diferentes formatos. Principalmente uso read_csv('file', encoding = "ISO-8859-1"), o alternativamente encoding = "utf-8"para leer, y generalmente utf-8para to_csv.

También puede usar una de varias aliasopciones como en 'latin'lugar de 'ISO-8859-1'(consulte los documentos de Python , también para muchas otras codificaciones que pueda encontrar).

Consulte la documentación relevante de Pandas , ejemplos de documentos de Python en archivos csv y muchas preguntas relacionadas aquí en SO. Un buen recurso de fondo es lo que todo desarrollador debe saber sobre los conjuntos de caracteres y Unicode .

Para detectar la codificación (suponiendo que el archivo contenga caracteres que no sean ascii), puede usar enca(consulte la página de manual ) o file -i(linux) o file -I(osx) (consulte la página de manual ).

Stefan
fuente
77
Dado que este es un problema de Windows, cp1252podría ser preferible iso-8859-1.
tzot
77
Gracias pd.read_csv('immigration.csv', encoding = "ISO-8859-1", engine='python')trabajó para mí
Mona Jalal
8
No asumas a ciegas que cierta codificación es la correcta solo porque no se produce ninguna excepción. Debe mirar las cadenas y descubrir si la interpretación tiene sentido. Por ejemplo, si obtiene "hors d'½uvre" en lugar de "hors d'œuvre", probablemente necesite cambiar de ISO-8859-1 a ISO-8859-15.
Joachim Wagner
66
para mí era la codificación ANSI. Para resolverlo, abrí el csv y notepadluego hice clic save as, allí muestra la codificación al lado del botón Guardar.
Vaibhav Vishal
69

La más simple de todas las soluciones:

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

Solución alternativa

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

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

Luego, puede leer su archivo como de costumbre:

import pandas as pd
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"
Gil Baggio
fuente
11
La pregunta explica que hay 30,000 de esos archivos. Abrir cada archivo manualmente no sería práctico.
Keith el
44
bueno, al menos para un archivo, ¡esto pareció funcionar para mí!
apil.tamang
El motor C es evidentemente más indulgente en lo que acepta. Para un archivo CSV particular que se abre bien con encoding='iso-8859-1', en su lugar, engine='python'lanza _csv.Error: field larger than field limit (131072).
Greg Bacon
1
¡Una solución alternativa para usar guardar con codificación fue realmente útil! así es como se usa para VSCode stackoverflow.com/questions/30082741/…
brownmagik352
20

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

  1. Conoces la codificación y no hay ningún error de codificación en el archivo. Genial: solo tiene 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 desea que le molesten las preguntas de codificación, y solo desea que se cargue ese maldito archivo, sin importar si algunos campos de texto contienen basura. Ok, solo tiene que usar la Latin1codificación porque acepta cualquier byte posible como entrada (y convertirlo 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 provisión para un procesamiento de error especial, pero la openfunción Python sí (suponiendo Python3), y read_csvacepta un archivo como objeto. Los parámetros de error típicos para usar aquí son los 'ignore'que simplemente suprimen los bytes ofensivos o (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, ...)
Serge Ballesta
fuente
1
Respuesta tardía, pero dirigida a una pregunta duplicada ...
Serge Ballesta
14
with open('filename.csv') as f:
   print(f)

después de ejecutar este código, encontrará la codificación de 'filename.csv' y luego ejecutará el código de la siguiente manera

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

ahí tienes

Bhavesh
fuente
6

En mi caso, un archivo tiene USC-2 LE BOMcodificación, de acuerdo con Notepad ++. Es encoding="utf_16_le"para python.

Espero que ayude a encontrar una respuesta un poco más rápido para alguien.

Vodyanikov Andrew Anatolevich
fuente
4

En mi caso, esto funcionó para Python 2.7:

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

Y para python 3, solo:

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

Intente especificar el motor = 'python'. Funcionó para mí, pero todavía estoy tratando de entender por qué.

df = pd.read_csv(input_file_path,...engine='python')
Ene33
fuente
Esto también funcionó para mí. También lo hizo encoding = "ISO-8859-1". Definitivamente es un problema de codificación. Si un carácter especial está codificado en ANSI, como un carácter de elipse (es decir, "...") e intenta leerlo en UTF-8, puede obtener un error. La conclusión es que debe conocer la codificación con la que se creó el archivo.
Sean McCarthy
3

Estoy publicando una respuesta para proporcionar una solución actualizada y una explicación de por qué puede ocurrir este problema. Supongamos que obtiene estos datos de una base de datos o libro de Excel. Si tiene caracteres especiales como La Cañada Flintridge city, bueno, a menos que esté exportando los datos mediante UTF-8codificación, introducirá errores. La Cañada Flintridge cityse convertirá La Ca\xf1ada Flintridge city. Si está utilizando pandas.read_csvsin ningún ajuste a los parámetros predeterminados, aparecerá el siguiente error

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

Afortunadamente, hay algunas soluciones.

Opción 1 , arregle la exportación. Asegúrese de usar la UTF-8codificación.

Opción 2 , si arreglar el problema exportador no está disponible para usted, y que necesita para su uso pandas.read_csv, asegúrese de incluir los siguientes parametros, engine='python'. De manera predeterminada, los pandas usan, lo engine='C'que es ideal para leer archivos grandes y limpios, pero se bloqueará si surge algo inesperado. En mi experiencia, la configuración encoding='utf-8'nunca ha solucionado esto UnicodeDecodeError. Además, no necesita usar errors_bad_lines, sin embargo, todavía es una opción si REALMENTE lo necesita.

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

Opción 3: la solución es mi solución preferida personalmente. Lea el archivo con 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)

Espero que esto ayude a las personas que se encuentran con este problema por primera vez.

Jon
fuente
2

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

Si está pasando un identificador de archivo pd.read_csv(),, debe poner el encodingatributo en el archivo abierto, no en read_csv. Obvio en retrospectiva, pero un error sutil para rastrear.

J. Ternent
fuente
2

Intenta agregar

encoding='unicode_escape'

Esto ayudará. Trabajó para mi. Además, asegúrese de usar el delimitador y los nombres de columna correctos.

Puede comenzar cargando solo 1000 filas para cargar el archivo rápidamente.

Prakhar Rathi
fuente
1

Esta respuesta parece ser el problema para los problemas de codificación CSV. Si tiene un extraño problema de codificación con su encabezado como este:

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

Entonces tiene un carácter de marca de orden de bytes (BOM) al comienzo de su archivo CSV. Esta respuesta aborda el problema:

Python read csv: lista de materiales incorporada en la primera clave

La solución es cargar el CSV con encoding="utf-8-sig":

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

Esperemos que esto ayude a alguien.

nbwoodward
fuente
1

Estoy publicando una actualización de este viejo hilo. Encontré una solución que funcionó, pero requiere abrir cada archivo. Abrí mi archivo csv en LibreOffice, elegí Guardar como> editar configuración de filtro. En el menú desplegable elegí la codificación UTF8. Luego agregué encoding="utf-8-sig"a la data = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig").

Espero que esto ayude a alguien.

tshirtdr1
fuente
Nisse, gracias por la edición. ¿Puedes explicar qué has cambiado? No veo la diferencia
tshirtdr1 01 de
1

Tengo problemas para abrir un archivo CSV en chino simplificado descargado de un banco en línea, lo he intentado latin1, lo he intentado iso-8859-1, lo he intentado cp1252, todo fue en vano.

Pero pd.read_csv("",encoding ='gbk')simplemente hace el trabajo.

Luk Aron
fuente
0

Estoy usando Jupyter-notebook. Y en mi caso, estaba mostrando el archivo en el formato incorrecto. La opción 'codificación' no funcionaba. Así que guardo el csv en formato utf-8 y funciona.

Himanshu Sharma
fuente
0

Prueba esto:

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

Parece que se encargará de la codificación sin expresarla explícitamente a través de argumentos

Ke Xu
fuente
0

Verifique la codificación antes de pasar a los pandas. Te retrasará, pero ...

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

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

En python 3.7

DaveP
fuente
0

Otro problema importante que enfrenté que resultó en el mismo error fue:

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

^ Esta línea resultó en el mismo error porque estoy leyendo un archivo de Excel usando el read_csv()método. Uso read_excel()para leer .xlxs

Mujeeb Ishaque
fuente
Wow, todos los demás están hablando de problemas de codificación. Parece que mi problema fue peculiar.
Mujeeb Ishaque
Es porque tienes un read_excelpandas.
Ani Menon
0

Puedes probar esto.

import csv
import pandas as pd
df = pd.read_csv(filepath,encoding='unicode_escape')
Dileep Dominic
fuente