UnicodeDecodeError ao ler o arquivo CSV no Pandas com Python

411

Estou executando um programa que está processando 30.000 arquivos semelhantes. Um número aleatório deles está parando e produzindo esse erro ...

   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

A origem / criação desses arquivos são todos do mesmo local. Qual é a melhor maneira de corrigir isso para prosseguir com a importação?

TravisVOX
fonte

Respostas:

823

read_csvtoma uma encodingopção para lidar com arquivos em diferentes formatos. Eu uso principalmente read_csv('file', encoding = "ISO-8859-1"), ou alternativamente, encoding = "utf-8"para leitura, e geralmente utf-8para to_csv.

Você também pode usar uma das várias aliasopções como ao 'latin'invés de 'ISO-8859-1'(consulte a documentação do python , também para inúmeras outras codificações que você pode encontrar).

Veja a documentação relevante do Pandas , exemplos de documentos python em arquivos csv e muitas perguntas relacionadas aqui no SO. Um bom recurso em segundo plano é o que todo desenvolvedor deve saber sobre conjuntos de caracteres e unicode .

Para detectar a codificação (assumindo que o arquivo contenha caracteres não-ascii), você pode usar enca(consulte a página de manual ) ou file -i(linux) ou file -I(osx) (consulte a página de manual ).

Stefan
fonte
7
Como esse é um problema do Windows, cp1252pode ser preferível iso-8859-1.
tzot
7
Graças pd.read_csv('immigration.csv', encoding = "ISO-8859-1", engine='python')trabalhou para mim
Mona Jalal
8
Não assuma cegamente que uma certa codificação é a correta apenas porque nenhuma exceção é lançada. Você precisa examinar as strings e descobrir se a interpretação faz sentido. Por exemplo, se você obtiver "hors d'½uvre" em vez de "hors d'œuvre", provavelmente precisará mudar de ISO-8859-1 para ISO-8859-15.
Joachim Wagner
6
para mim a codificação era ANSI. Para descobrir isso, eu abri o csv notepade clique em save as, lá mostra a codificação ao lado do botão Salvar.
Vaibhav Vishal
68

Soluções mais simples:

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

Solução alternativa:

  • Abra o arquivo csv no editor de texto sublime .
  • Salve o arquivo no formato utf-8.

No sublime, clique em Arquivo -> Salvar com codificação -> UTF-8

Em seguida, você pode ler seu arquivo como de costume:

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

e os outros tipos diferentes de codificação são:

encoding = "cp1252"
encoding = "ISO-8859-1"
Gil Baggio
fonte
11
A pergunta explica que existem 30.000 desses arquivos. Abrir cada arquivo manualmente não seria prático.
Keith # 20
4
bem, pelo menos para um arquivo, isso parecia funcionar para mim!
Apil.tamang
O mecanismo C é evidentemente mais tolerante no que aceita. Para um arquivo CSV específico que abre bem com encoding='iso-8859-1', em vez disso, engine='python'lança _csv.Error: field larger than field limit (131072).
Greg Bacon
1
solução alternativa para usar salvar com codificação foi realmente útil! aqui está como usá-lo para VSCode stackoverflow.com/questions/30082741/…
brownmagik352
20

O Pandas permite especificar a codificação, mas não permite ignorar erros para não substituir automaticamente os bytes incorretos. Portanto, não existe um tamanho único para todos os métodos, mas de maneiras diferentes, dependendo do caso de uso real.

  1. Você conhece a codificação e não há erro de codificação no arquivo. Ótimo: você só precisa especificar a codificação:

    file_encoding = 'cp1252'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
  2. Você não quer ser incomodado com perguntas de codificação e deseja que esse maldito arquivo seja carregado, independentemente de alguns campos de texto contiverem lixo. Ok, você só precisa usar a Latin1codificação porque aceita qualquer byte possível como entrada (e converte-o no caractere unicode do mesmo código):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
  3. Você sabe que a maior parte do arquivo é gravada com uma codificação específica, mas também contém erros de codificação. Um exemplo do mundo real é um arquivo UTF8 que foi editado com um editor não utf8 e que contém algumas linhas com uma codificação diferente. O Pandas não tem provisão para um processamento de erro especial, mas a openfunção Python possui (assumindo Python3) e read_csvaceita um arquivo como objeto. O parâmetro de erros típicos a ser usado aqui é o 'ignore'que apenas suprime os bytes incorretos ou (IMHO melhor) 'backslashreplace'que substitui os bytes incorretos pela sequência de escape com barra invertida do 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
fonte
1
Resposta final, mas direcionados a questão duplicado ...
Serge Ballesta
14
with open('filename.csv') as f:
   print(f)

Depois de executar este código, você encontrará a codificação de 'filename.csv' e, em seguida, executará o código da seguinte maneira

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

ai está

bhavesh
fonte
6

No meu caso, um arquivo possui USC-2 LE BOMcodificação, de acordo com o Notepad ++. Isto éencoding="utf_16_le" para python.

Espero que ajude a encontrar uma resposta um pouco mais rápida para alguém.

Vodyanikov Andrew Anatolevich
fonte
4

No meu caso, isso funcionou para o python 2.7:

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

E para python 3, apenas:

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

Tente especificar o engine = 'python'. Funcionou para mim, mas ainda estou tentando descobrir o porquê.

df = pd.read_csv(input_file_path,...engine='python')
Jan33
fonte
Isso também funcionou para mim. O mesmo fez codificação = "ISO-8859-1". Definitivamente, é um problema de codificação. Se um caractere especial estiver codificado em ANSI, como um caractere de elipse (ou seja, "..."), e você tentar lê-lo em UTF-8, poderá ocorrer um erro. A linha inferior é que você deve saber a codificação com a qual o arquivo foi criado.
Sean McCarthy
3

Estou postando uma resposta para fornecer uma solução atualizada e uma explicação de por que esse problema pode ocorrer. Digamos que você esteja obtendo esses dados de um banco de dados ou pasta de trabalho do Excel. Se você tiver caracteres especiais como La Cañada Flintridge city, bem, a menos que esteja exportando os dados usando UTF-8codificação, você introduzirá erros. La Cañada Flintridge cityvai se tornar La Ca\xf1ada Flintridge city. Se você estiver usando pandas.read_csvsem nenhum ajuste nos parâmetros padrão, verá o seguinte erro

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

Felizmente, existem algumas soluções.

Opção 1 , corrija a exportação. Certifique-se de usar a UTF-8codificação.

Opção 2 , se corrigir o problema de exportação não está disponível para você, e você precisa usar pandas.read_csv, certifique-se de incluir os seguintes paramters, engine='python'. Por padrão, o pandas usa o engine='C'que é ótimo para ler grandes arquivos limpos, mas falhará se surgir algo inesperado. Na minha experiência, a configuração encoding='utf-8'nunca corrigiu isso UnicodeDecodeError. Além disso, você não precisa usar errors_bad_lines, no entanto, isso ainda é uma opção se você REALMENTE precisar.

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

Opção 3: solução é minha solução preferida pessoalmente. Leia o arquivo usando o Python vanilla.

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 isso ajude as pessoas a encontrar esse problema pela primeira vez.

Jon
fonte
2

Lutou um pouco com isso e pensei em postar essa pergunta, já que é o primeiro resultado da pesquisa. Adicionando a encoding="iso-8859-1"tag aos pandasread_csv não funcionou, nem qualquer outra codificação, continuou fornecendo um UnicodeDecodeError.

Se você estiver passando um identificador de arquivo, pd.read_csv(),precisará colocar o encodingatributo no arquivo aberto, não em read_csv. Óbvio em retrospectiva, mas um erro sutil para rastrear.

J. Ternent
fonte
2

Por favor, tente adicionar

encoding='unicode_escape'

Isso vai ajudar. Trabalhou para mim. Além disso, verifique se você está usando o delimitador e os nomes de coluna corretos.

Você pode começar carregando apenas 1000 linhas para carregar o arquivo rapidamente.

Prakhar Rathi
fonte
1

Essa resposta parece ser a solução para problemas de codificação de CSV. Se você está tendo um problema de codificação estranho com o cabeçalho desta maneira:

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

Então você tem um caractere de marca de ordem de byte (BOM) no início do seu arquivo CSV. Esta resposta soluciona o problema:

Python leia csv - BOM incorporada na primeira chave

A solução é carregar o CSV com encoding="utf-8-sig":

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

Espero que isso ajude alguém.

nbwoodward
fonte
1

Estou postando uma atualização para este tópico antigo. Encontrei uma solução que funcionou, mas requer a abertura de cada arquivo. Abri meu arquivo csv no LibreOffice, escolha Salvar como> editar configurações de filtro. No menu suspenso, escolhi a codificação UTF8. Então eu adicionei encoding="utf-8-sig"aodata = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig") .

Espero que isso ajude alguém.

tshirtdr1
fonte
Nisse, obrigado pela edição. Você pode, por favor, explicar o que mudou? Não vejo diferença.
precisa saber é o seguinte
1

Estou com problemas para abrir um arquivo CSV em chinês simplificado baixado de um banco online, tentei latin1, tentei iso-8859-1, tenteicp1252 , tudo sem sucesso.

Mas pd.read_csv("",encoding ='gbk')simplesmente faz o trabalho.

Luk Aron
fonte
0

Estou usando o notebook Jupyter. E no meu caso, estava mostrando o arquivo no formato errado. A opção 'codificação' não estava funcionando. Então, eu salvo o csv no formato utf-8, e ele funciona.

Himanshu Sharma
fonte
0

Tente o seguinte:

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

Parece que ele cuidará da codificação sem expressá-la explicitamente através de argumentos

Ke Xu
fonte
0

Verifique a codificação antes de passar para os pandas. Isso vai te atrapalhar, mas ...

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

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

No python 3.7

DaveP
fonte
0

Outra questão importante que eu enfrentei que resultou no mesmo erro foi:

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

^ Esta linha resultou no mesmo erro porque estou lendo um arquivo do Excel usando o read_csv()método Use read_excel()para ler .xlxs

Mujeeb Ishaque
fonte
Uau, todo mundo está falando sobre problemas de codificação. Parece que meu problema foi peculiar.
Mujeeb Ishaque 21/04
É porque você tem um read_excelem pandas.
Ani Menon
0

Você pode tentar isso.

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