Saltar al contenido

lección 5

Formatos avanzados: Parquet y por qué cambia las reglas del juego

Del texto plano al formato binario columnar. Compresión, velocidad y por qué las empresas dejaron de usar CSV para datos grandes.

55 min

Imagina que trabajas en una empresa que procesa 5 millones de pedidos al día. Cada pedido tiene 20 campos: id, fecha, cliente, producto, precio, cantidad, descuento, impuestos, dirección, ciudad, país, método de pago, estado del envío... Los guardas en CSV porque es lo que conoces. El archivo diario pesa 2 GB. En un mes tienes 60 GB. En un año, 730 GB. Y cuando el director financiero te pide "el total de ventas por país del último trimestre", tu script tiene que leer 180 GB de datos — incluyendo los 18 campos que NO necesita (dirección, producto, estado del envío...) — solo para sumar una columna.

Esto es como si para saber cuántas personas viven en cada planta de un edificio, tuvieras que entrar en cada apartamento, revisar toda la casa (dormitorios, cocina, baños) y apuntar solo el número de habitantes. No tiene sentido. Lo eficiente sería tener un buzón en cada planta con un cartel que dice "3 personas". Eso es exactamente lo que hace el formato columnar: organizar los datos para que puedas leer SOLO las columnas que necesitas sin tocar las demás.

### Almacenamiento por filas vs por columnas

CSV almacena datos POR FILAS: toda la información de un registro está junta. Para leer una sola columna, tienes que leer TODAS las filas completas. Parquet almacena datos POR COLUMNAS: todos los valores de una columna están juntos. Para leer una sola columna, solo lees esa columna — ignoras las demás.

La diferencia fundamental: por filas vs por columnas

### ¿Por qué columnar es más rápido para análisis?

Cuando haces análisis, normalmente necesitas pocas columnas de muchas filas: "suma el importe de todos los pedidos" (solo necesitas la columna importe), "cuenta pedidos por país" (solo necesitas país). Con formato de filas (CSV), lees TODO para extraer UNA columna. Con formato columnar (Parquet), lees SOLO la columna que necesitas. Si tu tabla tiene 20 columnas y solo necesitas 2, Parquet lee el 10% de los datos. Eso es 10x más rápido.

### La compresión: datos más pequeños automáticamente

Hay otra ventaja enorme del formato columnar: la compresión. Cuando los datos de una misma columna están juntos, se comprimen muchísimo mejor. ¿Por qué? Porque una columna tiene datos del mismo tipo y rango. Una columna "país" tendrá valores repetidos (España, España, Francia, España, Alemania...) — se comprime fácil. Una columna "edad" tendrá números entre 18 y 90 — se comprime bien. En cambio, comprimir una fila completa (texto + número + fecha + booleano) es mucho menos eficiente porque los datos son heterogéneos.

Resultado práctico: un archivo CSV de 2 GB se convierte en un Parquet de 200-400 MB. Mismo contenido, 5-10x menos espacio. Eso significa menos disco, menos ancho de banda al transferir y menos memoria al procesarlo.

### Parquet tiene esquema: adiós a la ambigüedad

Recuerda los problemas de CSV: ¿el "42" es un número o un código postal? CSV no lo sabe. Parquet SÍ. El archivo Parquet incluye metadatos que describen cada columna: nombre, tipo de dato, si admite nulos, estadísticas (valor mínimo, máximo, count). Cuando lees un Parquet, sabes desde el primer byte que la columna "edad" es Integer y la columna "nombre" es String. No hay ambigüedad, no hay conversión manual.

Consejo de senior: Parquet es el formato estándar de la industria para almacenamiento analítico. Si estás guardando datos para análisis posterior (no para intercambio humano), usa Parquet. Siempre. Sin excepción. El ahorro de espacio y tiempo se multiplica con el volumen.

### Demo práctica: CSV vs Parquet con Python

Vamos a verlo en acción. Para trabajar con Parquet en Python necesitas instalar la librería pyarrow. Es una librería de la Apache Software Foundation que implementa el formato Parquet (y muchas cosas más). Vamos a instalarla y comparar CSV vs Parquet con datos reales.

1# 🟦 Windows (PowerShell)
2pip install pyarrow
3
4# 🍎 Mac (Terminal)
5pip install pyarrow

Instalar pyarrow: la librería para leer/escribir Parquet

1import csv
2import json
3import os
4import pyarrow as pa
5import pyarrow.parquet as pq
6import time
7
8# Generar datos de ejemplo: 100.000 pedidos
9import random
10random.seed(42)
11
12pedidos = []
13ciudades = ["Madrid", "Barcelona", "Sevilla", "Valencia", "Bilbao"]
14productos = ["Camiseta", "Pantalón", "Zapatos", "Chaqueta", "Bufanda"]
15
16for i in range(100_000):
17 pedidos.append({
18 "id": i + 1,
19 "fecha": f"2026-01-{random.randint(1,28):02d}",
20 "cliente_id": random.randint(1, 10000),
21 "producto": random.choice(productos),
22 "precio": round(random.uniform(10, 200), 2),
23 "cantidad": random.randint(1, 5),
24 "ciudad": random.choice(ciudades),
25 })
26
27# --- Guardar como CSV ---
28with open("pedidos.csv", "w", newline="", encoding="utf-8") as f:
29 writer = csv.DictWriter(f, fieldnames=pedidos[0].keys())
30 writer.writeheader()
31 writer.writerows(pedidos)
32
33# --- Guardar como Parquet ---
34tabla = pa.table({
35 "id": [p["id"] for p in pedidos],
36 "fecha": [p["fecha"] for p in pedidos],
37 "cliente_id": [p["cliente_id"] for p in pedidos],
38 "producto": [p["producto"] for p in pedidos],
39 "precio": [p["precio"] for p in pedidos],
40 "cantidad": [p["cantidad"] for p in pedidos],
41 "ciudad": [p["ciudad"] for p in pedidos],
42})
43pq.write_table(tabla, "pedidos.parquet")
44
45# --- Comparar tamaños ---
46tam_csv = os.path.getsize("pedidos.csv") / (1024 * 1024)
47tam_parquet = os.path.getsize("pedidos.parquet") / (1024 * 1024)
48print(f"CSV: {tam_csv:.2f} MB")
49print(f"Parquet: {tam_parquet:.2f} MB")
50print(f"Ratio: {tam_csv/tam_parquet:.1f}x más pequeño")

Comparación real: 100K pedidos en CSV vs Parquet. Mide el tamaño.

1import pyarrow.parquet as pq
2
3# --- Leer SOLO una columna de Parquet (column pruning) ---
4# En CSV tendrías que leer TODO el archivo
5tabla_parcial = pq.read_table("pedidos.parquet", columns=["ciudad", "precio"])
6print(f"Columnas leídas: {tabla_parcial.column_names}")
7print(f"Filas: {len(tabla_parcial)}")
8
9# Convertir a Python para trabajar
10ciudades = tabla_parcial.column("ciudad").to_pylist()
11precios = tabla_parcial.column("precio").to_pylist()
12
13# Calcular total por ciudad (solo leyendo 2 de 7 columnas)
14ventas_ciudad = {}
15for ciudad, precio in zip(ciudades, precios):
16 ventas_ciudad[ciudad] = ventas_ciudad.get(ciudad, 0) + precio
17
18print("\nVentas por ciudad:")
19for ciudad, total in sorted(ventas_ciudad.items(), key=lambda x: -x[1]):
20 print(f" {ciudad:12}{total:>12,.2f}€")
21
22# --- Ver metadatos del archivo ---
23metadata = pq.read_metadata("pedidos.parquet")
24print(f"\nMetadatos Parquet:")
25print(f" Filas totales: {metadata.num_rows:,}")
26print(f" Columnas: {metadata.num_columns}")
27print(f" Row groups: {metadata.num_row_groups}")

Column pruning: leer solo las columnas necesarias de un Parquet

Parquet NO es para todo. Si necesitas que un humano abra el archivo y lo lea (enviar al jefe, compartir con un proveedor que usa Excel), usa CSV. Si necesitas editar una fila específica, Parquet no es buena opción (es un formato de append, no de update). Parquet brilla para almacenamiento analítico de grandes volúmenes que se leen frecuentemente pero se escriben una vez.

### Resumen: cuándo usar qué formato

  • CSV: intercambio humano, archivos pequeños (<100 MB), compatibilidad con Excel, datos para un proveedor externo.
  • JSON/JSONL: APIs, logs de aplicaciones, datos semiestructurados, configuración.
  • Parquet: almacenamiento analítico, datos grandes (>100 MB), lectura frecuente de pocas columnas, archivos de larga duración.

Esta es tu primera introducción a Parquet. En la Skill 12 (Data Lakes) profundizarás en row groups, compresión por columna, predicate pushdown y PyArrow — todo lo que necesitas para trabajar con Parquet a escala de producción.

Regla del pulgar que uso desde hace 10 años: si el archivo se lee más de 3 veces, conviértelo a Parquet. El coste de conversión se amortiza en la primera lectura. Si solo se lee una vez y se descarta, CSV o JSONL están bien.

Sobre librerías Parquet: en esta lección verás pandas (df.to_parquet, pd.read_parquet) y pyarrow (pq.read_metadata, pq.write_table). En la práctica, pandas usa pyarrow por debajo — así que son la misma tecnología. Usa pandas para leer/escribir DataFrames y pyarrow cuando quieras control fino (metadatos, esquemas, row groups). No necesitas instalar nada extra: pip install pandas ya trae pyarrow como dependencia.

## ejercicios

[01]

Convierte un CSV de ventas a Parquet y compara tamaños

Genera un CSV con 50.000 registros de ventas, conviértelo a Parquet con pandas y muestra la diferencia de tamaño.

Cargando editor...
[02]

Inspeccionar metadatos de un Parquet

Lee los metadatos de un archivo Parquet sin cargar los datos. El tipo de columna puede salir "string" o "large_string" según tu versión de pyarrow: ambas son correctas.

Cargando editor...
[03]

Column pruning: lee solo lo que necesitas

El CEO quiere el total de ventas por producto. Lee SOLO las columnas necesarias del Parquet (no todas) y calcula el resultado.

Cargando editor...
[04]

Benchmark: mide la velocidad CSV vs Parquet

Compara el tiempo de leer una columna de CSV (leyendo todo) vs Parquet (column pruning). Los tiempos dependen de tu máquina.

Cargando editor...

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...