Skip to content
Empieza gratis

¿Cómo arreglo un CSV que trae todos los problemas juntos?

Diagnostica y lee con DuckDB un archivo de pedidos con punto y coma, BOM, coma decimal, miles, códigos con ceros, fechas día/mes y nombres que alguien ya guardó rotos.

Curso gratis. Tu Maestro, una IA, .

Fin de mes. Contabilidad te manda pedidos_sucursal.csv para el reporte, y trae de todo. Antes de abrirlo en cualquier programa, léelo como texto, como en el módulo 1:

datos/pedidos_sucursal.csv
folio;fecha;cliente;codigo_postal;sku;cantidad;importe
000101;02/09/2026;Papelería La Única;44100;00731;40;940,00
000102;05/09/2026;Abarrotes Doña Peña;06700;01204;12;1.416,00
000103;03/10/2026;Farmacia San José;45640;00090;150;1.485,00
000104;07/10/2026;Miscelánea El Güero;06700;00731;25;587,50
000105;11/10/2026;Papelería La Única;44100;09810;2;2.360,00
Datos sintéticos, CC0. El archivo, visto como texto, sin su BOM.

Y el archivo empieza con un BOM. Haz la lista tú antes de seguir leyendo: ¿cuántos problemas ves?

Hay seis, uno por cada tema del curso:

Lo que vesQué esCómo se le dice al lector (DuckDB)
; entre columnasEl separador de una región con coma decimaldelim=';'
940,00 y 1.416,00Coma decimal y punto de milesdecimal_separator=',', thousands='.'
000101, 06700, 00731Códigos que empiezan con cerotypes={'folio': 'VARCHAR', ...}
02/09/2026Fecha día/mes/año, con todos los días del 1 al 12dateformat='%d/%m/%Y'
Tres bytes al inicioEl BOMDuckDB lo quitó solo en la caja de arena
Doña PeñaMojibake ya guardado en el archivoRepararlo después de leer

El último es distinto de los demás, y es la lección más fina del curso. En el módulo 1, Mérida aparecía porque tú leías un archivo UTF-8 con la tabla equivocada: cambiando la lectura se arreglaba. Aquí no. Alguien en contabilidad ya abrió el archivo con la tabla equivocada, vio Doña, y lo guardó así. Ahora el archivo es UTF-8 válido que contiene, letra por letra, à y ±. Ninguna codificación al leer lo arregla, porque la lectura no está mal: lo que está mal es el texto. Lo reparas con la receta del módulo 1: texto.encode("cp1252").decode("utf-8"), que deshace exactamente ese error.

  1. Mira el archivo como texto

  2. ¿Los acentos se ven raros?

    • Camino 1 de 2: no es UTF-8

      1. Cambia la codificación al leer

        si el archivo no está en UTF-8

      Sigue en: Separador, decimales y miles

    • Camino 2 de 2: ya dice à en UTF-8

      1. Repara el texto después de leer

        si ya se guardó roto

      Sigue en: Separador, decimales y miles

  3. Separador, decimales y miles

  4. Códigos como texto y formato de fecha

  5. Revisa tipos y totales

Las preguntas en orden; cada respuesta se vuelve una opción del lector.

DuckDB para leer, a la vista

En este proyecto lees con DuckDB, dentro de Python. Su read_csv acepta las mismas decisiones que ya conoces de pandas, con otros nombres, y las escribes dentro de la consulta. DuckDB también adivina: en la caja de arena detectó solo el punto y coma, dejó los folios como texto y leyó bien las fechas. Pero el importe se quedó como texto. Y si le pides solo decimal_separator=',', sin thousands, lo deja como texto sin avisar; si además le exiges que sea número, se detiene con un error que dice qué línea y qué valor no pudo convertir, 1.416,00. Ese error te conviene: te dice dónde mirar.

Aunque DuckDB adivine bien la fecha o los folios, escríbelo. El mes que llegue un archivo distinto, tu script seguirá leyendo igual.

Si DuckDB te da un error de conversión, pégaselo a tu Maestro y lo leen juntos.

Inténtalo, ahora solo

El script reporte.py lee el archivo sin opciones y repara los nombres con una función que todavía no hace nada. Córrelo con uv run reporte.py y mira los tipos y los totales: el importe sale como texto pegado y los clientes con garabatos. Arréglalo tú, sin pistas en el código: la tabla de arriba tiene todo lo que necesitas. Si te atoras, pregúntale a tu Maestro por el siguiente paso, no por la solución.

Tu turno

Corre uv run reporte.py. Cambia solo la parte de arriba del script: las opciones de read_csv y la función reparar. Ya quedó cuando importe es float64, los nombres se leen bien ("Papelería La Única"), las ventas por mes son 9: 2356.0 y 10: 4432.5, y el primer cliente por ventas es Papelería La Única con 3300.0.

    Python 3.12· corre con tu cuenta

    Cuando tu reporte cuadre, fíjate en qué dice tu read_csv: cada opción es una respuesta a una de las preguntas del diagrama. Quien lea tu script después sabe cómo viene el archivo sin abrirlo.

    Y un último cuidado con reparar: úsala solo en texto que de verdad está roto. En la caja de arena, aplicada a un nombre sano como Mérida, falla con UnicodeDecodeError, porque no hay error que deshacer. Si en un archivo vienen nombres rotos y nombres sanos mezclados, la reparación tiene que ser fila por fila, y conviene pedir a tu Maestro que te ayude a escribirla.

    Comprueba lo que sabes: Lees un archivo en UTF-8 con la codificación correcta y aun así los nombres dicen "Doña Peña". ¿Qué pasó y qué haces?