Arreglar la codificación de caracteres en Python y pandas

¿pandas lee ñ en vez de ñ, se detiene con un UnicodeDecodeError o Excel muestra mal tu CSV exportado? En Python, el parámetro encoding decide entre bien y roto. Aquí están los casos típicos; los archivos rotos los reparas arriba, en el navegador.

Funciona con texto y con estos archivos:

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

Por ejemplo exportaciones de Excel, copias de bases de datos, subtítulos o código web.

Reparar

  1. Suelta un archivo o pega texto
  2. Se repara automáticamente
  3. Copia o descarga
o simplemente arrastra un archivo aquí

UnicodeDecodeError al leer

pd.read_csv espera UTF-8. Si el archivo está guardado en Windows-1252 (ANSI), pandas se detiene con UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1; 0xF1 es la ñ en Windows-1252. Entonces indica la codificación:

  • pd.read_csv('datos.csv', encoding='cp1252') para archivos de Excel y Windows.
  • encoding='latin-1' nunca falla, pero lee mal el € y las comillas tipográficas; cp1252 suele ser mejor opción.
  • Si no conoces la codificación, suelta el archivo en Mojibuster: la detecta y lo guarda como UTF-8.

ñ en vez de ñ en el DataFrame

Si el DataFrame muestra ñ, se leyó un archivo UTF-8 como latin-1 o cp1252, o los datos ya estaban rotos. En el primer caso basta encoding='utf-8'. Si los propios datos están rotos, valor.encode('cp1252').decode('utf-8') sirve para valores sueltos. Con datos mezclados falla en cuanto una celda ya es correcta. Más fácil: repara el archivo con Mojibuster y luego léelo.

Un CSV de pandas abierto en Excel sin BOM

Antes

nombre,ciudad,ventas
José Muñoz,Málaga,1250 €
Anaïs Pérez,Peñíscola,980 €

Después

nombre,ciudad,ventas
José Muñoz,Málaga,1250 €
Anaïs Pérez,Peñíscola,980 €

to_csv: Excel muestra mal el archivo

df.to_csv('exportacion.csv') escribe UTF-8 sin BOM. Excel abre esos archivos como ANSI y las letras con tilde se convierten en ñ. Con encoding='utf-8-sig', pandas escribe un BOM y Excel reconoce el UTF-8. Más sobre Excel con caracteres raros.

open() en Windows

open('archivo.txt') sin encoding usa en Windows la codificación del sistema, normalmente cp1252. Un script que funciona en Linux lee entonces el mismo archivo UTF-8 como ñ en Windows. Pasa siempre encoding='utf-8' o define la variable de entorno PYTHONUTF8=1. Con la PEP 686, UTF-8 será de todos modos el valor predeterminado en futuras versiones de Python.

Datos web con requests

requests deduce response.text de la cabecera Content-Type. Si una respuesta de texto no indica allí el juego de caracteres, supone ISO-8859-1 y las páginas UTF-8 muestran ñ. Define antes response.encoding = 'utf-8' o usa response.json(), que detecta UTF-8 por sí solo.

Si el texto se escribió con errors='replace' en una codificación sin los caracteres necesarios, el archivo contiene ?; entonces la información se perdió, mira signos de interrogación en vez de acentos.

Preguntas frecuentes

¿Hay una librería de Python para esto?

Sí, ftfy corrige mojibake desde código Python. Para archivos sueltos y sin programar, Mojibuster es más rápido y te muestra cada cambio antes de guardar.

¿Qué valores de encoding necesito más?

utf-8, utf-8-sig (UTF-8 con BOM), cp1252 (Windows, Europa occidental), latin-1 y utf-16. No importan las mayúsculas ni los guiones.

¿Se conservan los separadores y los números?

Sí. Mojibuster solo cambia los caracteres rotos. Comas, comillas y saltos de línea quedan exactamente igual.

Más guías