Corrigir a codificação de caracteres no Python e no pandas

O pandas lê ç no lugar de ç, para com um UnicodeDecodeError ou o Excel mostra errado o seu CSV exportado? No Python, o parâmetro encoding decide entre certo e quebrado. Aqui estão os casos típicos; arquivos quebrados você repara acima, no navegador.

Funciona com texto e com estes arquivos:

  • CSV
  • TXT
  • JSON
  • XML
  • SRT
  • VTT
  • SMI
  • TSV
  • MD
  • HTML
  • SQL
  • LOG

Por exemplo exportações do Excel, backups de bancos de dados, legendas ou código de sites.

Corrigir

  1. Solte um arquivo ou cole o texto
  2. A correção é automática
  3. Copie ou baixe
ou simplesmente arraste um arquivo para cá

UnicodeDecodeError ao ler

O pd.read_csv espera UTF-8. Se o arquivo está salvo em Windows-1252 (ANSI), o pandas para com UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe7; 0xE7 é o ç em Windows-1252. Então informe a codificação:

  • pd.read_csv('dados.csv', encoding='cp1252') para arquivos do Excel e do Windows.
  • encoding='latin-1' nunca falha, mas lê errado o € e as aspas tipográficas; cp1252 costuma ser a melhor escolha.
  • Se você não sabe a codificação, solte o arquivo no Mojibuster: ele a detecta e salva o arquivo em UTF-8.

ç no lugar de ç no DataFrame

Se o DataFrame mostra ç, um arquivo UTF-8 foi lido como latin-1 ou cp1252, ou os dados já estavam quebrados. No primeiro caso, encoding='utf-8' resolve. Se os próprios dados estão quebrados, valor.encode('cp1252').decode('utf-8') ajuda em valores isolados. Com dados misturados, porém, falha assim que uma célula já está correta. Mais fácil: repare o arquivo com o Mojibuster e depois leia.

Um CSV do pandas aberto no Excel sem BOM

Antes

nome,cidade,receita
João Conceição,São Paulo,1250 €
Ângela Pereira,Maceió,980 €

Depois

nome,cidade,receita
João Conceição,São Paulo,1250 €
Ângela Pereira,Maceió,980 €

to_csv: o Excel mostra o arquivo errado

df.to_csv('exportacao.csv') grava UTF-8 sem BOM. O Excel abre esses arquivos como ANSI e as letras acentuadas viram ç. Com encoding='utf-8-sig', o pandas grava um BOM e o Excel reconhece o UTF-8. Mais sobre Excel com acentos errados.

open() no Windows

open('arquivo.txt') sem encoding usa no Windows a codificação do sistema, normalmente cp1252. Um script que funciona no Linux lê então o mesmo arquivo UTF-8 como ç no Windows. Por isso passe sempre encoding='utf-8' ou defina a variável de ambiente PYTHONUTF8=1. Com a PEP 686, o UTF-8 vai virar o padrão em versões futuras do Python.

Dados da web com requests

O requests deduz response.text do cabeçalho Content-Type. Se uma resposta de texto não informa ali o charset, ele presume ISO-8859-1 e páginas UTF-8 mostram ç. Defina antes response.encoding = 'utf-8' ou use response.json(), que detecta UTF-8 sozinho.

Se o texto foi gravado com errors='replace' em uma codificação sem os caracteres necessários, o arquivo contém ?; aí a informação se perdeu, veja interrogação no lugar de acentos.

Perguntas frequentes

Existe uma biblioteca Python para isso?

Sim, o ftfy corrige mojibake em código Python. Para arquivos avulsos, sem programar, o Mojibuster é mais rápido e mostra cada alteração antes de salvar.

Quais valores de encoding mais uso?

utf-8, utf-8-sig (UTF-8 com BOM), cp1252 (Windows, Europa Ocidental), latin-1 e utf-16. Maiúsculas e hifens não importam.

Separadores e números são mantidos?

Sim. O Mojibuster só altera caracteres quebrados. Vírgulas, aspas e quebras de linha ficam exatamente como estão.

Mais guias