lección 2
Leer cualquier cosa: CSV, JSON, Excel, Parquet con Pandas
Domina la lectura de los 4 formatos más comunes y entiende cuándo usar cada uno.
⏱ 55 min
### El problema de los mil formatos
En el mundo real, los datos no llegan limpios ni en un formato estándar. Un proveedor te manda un Excel con macros. El equipo de producto exporta a CSV con separador punto y coma (porque son europeos). El frontend genera logs en JSON anidado. Y el data lake almacena en Parquet porque alguien leyó que era más eficiente. Tu trabajo como ingeniero de datos es leerlos TODOS sin pestañear.
Pandas es políglota: sabe leer decenas de formatos. Pero los 4 que usarás el 95% del tiempo son CSV, JSON, Excel y Parquet. Cada uno tiene sus trampas y sus parámetros clave. Vamos a dominarlos uno a uno.
### CSV: el formato universal (y sus 47 variantes)
CSV significa "Comma Separated Values". Suena simple: valores separados por comas. Pero en la práctica te encontrarás: separadores que no son comas (punto y coma, tabulador, pipe), encodings que corrompen acentos (UTF-8, Latin-1, Windows-1252), cabeceras que faltan o están en la fila 3, y fechas en 15 formatos distintos. read_csv tiene más de 50 parámetros por algo.
1import pandas as pd23# Lectura básica — funciona si tienes suerte4df = pd.read_csv('ventas.csv')56# Lectura defensiva — para el mundo real7df = pd.read_csv(8 'ventas_europa.csv',9 sep=';', # Separador europeo10 encoding='latin-1', # Encoding para acentos11 parse_dates=['fecha'], # Convierte strings a datetime12 decimal=',', # Decimal europeo (1.234,56)13 na_values=['N/A', '-', ''], # Valores que significan "no hay dato"14 dtype={'codigo_postal': str} # Forzar tipo (evita que 08001 sea 8001)15)1617print(df.head())18print(df.dtypes)
read_csv defensivo: los parámetros que necesitarás en el 80% de CSVs reales
Consejo de senior: la primera vez que leas un CSV nuevo, SIEMPRE mira las primeras líneas en un editor de texto (VS Code) antes de cargarlo en Pandas. Así descubres el separador, el encoding y las sorpresas ANTES de pelear con errores crípticos de pandas.
Trampa clásica: códigos postales, teléfonos y IDs que empiezan por 0 (como 08001 Barcelona). Si Pandas los interpreta como números, el 0 desaparece y 08001 se convierte en 8001. SIEMPRE usa dtype={"columna": str} para columnas con ceros a la izquierda.
### JSON: el formato de las APIs
JSON es el idioma de las APIs web. Cuando tu app se comunica con un servidor, los datos viajan en JSON. El problema es que JSON puede estar anidado (objetos dentro de objetos dentro de listas) y Pandas espera datos planos (filas y columnas). Ahí entra json_normalize.
1import pandas as pd23# JSON plano (cada elemento = una fila) — fácil4df = pd.read_json('usuarios.json')56# JSON anidado — necesitas aplanarlo7import json89with open('pedidos_api.json') as f:10 data = json.load(f)1112# Si la estructura es: [{"id": 1, "cliente": {"nombre": "Ana", "ciudad": "Madrid"}, "total": 150}]13df = pd.json_normalize(14 data,15 sep='_' # cliente.nombre → cliente_nombre16)17print(df.columns.tolist())18# ['id', 'total', 'cliente_nombre', 'cliente_ciudad']
json_normalize aplana estructuras anidadas en columnas con prefijo
### Excel: el formato del "business"
Te guste o no, Excel sigue siendo el rey en departamentos de finanzas, RRHH y operaciones. Recibirás archivos .xlsx con múltiples hojas, celdas fusionadas, fórmulas y formatos. Pandas puede leerlos, pero necesita la librería openpyxl como motor.
1# Instalar el motor para Excel2pip install openpyxl==3.1.5
openpyxl es necesario para leer archivos .xlsx
1import pandas as pd23# Leer la primera hoja4df = pd.read_excel('informe_financiero.xlsx')56# Leer una hoja específica7df = pd.read_excel('informe_financiero.xlsx', sheet_name='Q4_2024')89# Leer TODAS las hojas → devuelve un diccionario {nombre_hoja: DataFrame}10todas = pd.read_excel('informe_financiero.xlsx', sheet_name=None)11for nombre, datos in todas.items():12 print(f"Hoja '{nombre}': {datos.shape}")1314# Saltar filas de cabecera decorativa15df = pd.read_excel(16 'informe_financiero.xlsx',17 header=2, # La fila 3 es la cabecera real (0-indexed)18 usecols='B:F' # Solo columnas B a F19)
Lectura de Excel: hojas, cabeceras y selección de columnas
### Parquet: el formato del ingeniero de datos
Parquet es el formato columnar creado por el ecosistema Apache (Hadoop, Spark) para almacenar datos analíticos de forma eficiente. ¿Por qué columnar? Porque las consultas analíticas típicas leen pocas columnas de muchas filas (ej: "dame la suma de ventas" solo necesita la columna ventas, no las 50 columnas restantes). Parquet comprime los datos 5-10x comparado con CSV y los lee mucho más rápido.
1# Instalar el motor para Parquet2pip install pyarrow==16.1.0
PyArrow es el motor recomendado para Parquet en Pandas
1import pandas as pd23# Leer Parquet — es así de simple4df = pd.read_parquet('ventas_historico.parquet')56# Leer SOLO las columnas que necesitas (predicate pushdown)7df = pd.read_parquet(8 'ventas_historico.parquet',9 columns=['fecha', 'producto', 'importe']10)1112# Guardar un DataFrame como Parquet13df.to_parquet('resultado.parquet', index=False)1415# Comparación de tamaños (ejemplo real):16# ventas.csv → 450 MB17# ventas.parquet → 52 MB (¡88% más pequeño!)
Parquet: más rápido, más compacto, con tipos preservados
Regla de oro para formatos: CSV para intercambio rápido con humanos, JSON para APIs, Excel para enviar al CFO, Parquet para almacenar datos entre etapas de tu pipeline. Si guardas datos intermedios en CSV estás malgastando disco y tiempo de lectura.
### Tabla resumen: cuándo usar cada formato
### Escribir datos: to_csv, to_json, to_parquet
Leer es solo la mitad. Después de transformar los datos, necesitas guardarlos. Pandas ofrece métodos to_* simétricos a los read_*.
1import pandas as pd23df = pd.DataFrame({4 'cliente': ['Ana', 'Carlos', 'Lucía'],5 'total_compras': [1500, 3200, 800],6 'fecha_ultimo_pedido': pd.to_datetime(['2024-01-15', '2024-03-20', '2024-02-10'])7})89# Guardar como CSV (para enviar a alguien)10df.to_csv('resumen_clientes.csv', index=False)1112# Guardar como JSON (para una API)13df.to_json('resumen_clientes.json', orient='records', date_format='iso')1415# Guardar como Parquet (para tu pipeline)16df.to_parquet('resumen_clientes.parquet', index=False)1718# Guardar como Excel (para el jefe)19df.to_excel('resumen_clientes.xlsx', index=False, sheet_name='Resumen')
Guardar en distintos formatos: index=False evita la columna de índice innecesaria
Cuando guardas en CSV, Pandas escribe el índice por defecto (esa columna 0,1,2... que no sirve para nada). SIEMPRE usa index=False a menos que tu índice tenga significado real (como fechas en una serie temporal).
### Truco pro: leer solo lo que necesitas
Con archivos grandes, cargar todo en memoria es un desperdicio si solo necesitas unas columnas o unas filas. Pandas permite leer de forma parcial:
1import pandas as pd23# Solo las columnas que necesitas4df = pd.read_csv('ventas_grande.csv', usecols=['fecha', 'producto', 'importe'])56# Solo las primeras N filas (para explorar)7df = pd.read_csv('ventas_grande.csv', nrows=1000)89# Lectura por chunks (para archivos que no caben en RAM)10for chunk in pd.read_csv('ventas_enorme.csv', chunksize=100_000):11 # Procesar cada trozo de 100K filas12 resultado = chunk.groupby('producto')['importe'].sum()13 print(resultado.head())
Lectura parcial: usecols, nrows y chunksize para archivos grandes
## ejercicios
El CSV del proveedor europeo
Te llega un CSV de un proveedor alemán con separador punto y coma, decimales con coma (1.234,56), encoding latin-1 y la columna "plz" (código postal) tiene ceros a la izquierda. Escribe el read_csv correcto.
💡 Resultado esperado
lieferant produkt plz datum preis 0 Müller GmbH Schraube 01234 2024-03-05 1234.56 1 Schäfer AG Mutter 09876 2024-06-04 2500.00 2 Weiß KG Bolzen 00543 2024-09-11 999.99
Aplanar JSON de una API de e-commerce
La API de tu e-commerce devuelve pedidos con estructura anidada: {"id": 1, "cliente": {"nombre": "Ana", "ciudad": "Madrid"}, "items": 3, "total": 150.5}. Usa json_normalize para convertirlo en un DataFrame plano.
💡 Resultado esperado
id items total cliente_nombre cliente_ciudad 0 1 3 150.5 Ana Madrid 1 2 1 45.0 Carlos Barcelona 2 3 5 320.0 Lucía Sevilla
Convertir CSV a Parquet para el data lake
El equipo de BI se queja de que leer el CSV de ventas tarda 3 minutos. Tu misión: leer el CSV, quedarte solo con las columnas necesarias (fecha, producto_id, cantidad, importe) y guardarlo como Parquet.
💡 Resultado esperado
Filas: 200 Columnas: ['fecha', 'producto_id', 'cantidad', 'importe']
Regístrate para guardar tu progreso.
## comentarios
Reporta erratas, ayuda a otros o comparte tu opinión. Sé constructivo.
Inicia sesión para comentar y responder.
cargando comentarios...