Pandas leyendo archivos Parquet / Feather
Parquet y Feather son dos formatos eficientes de almacenamiento de datos en columnas, diseñados específicamente para el análisis de big data y escenarios de lectura/escritura rápidos. En comparación con CSV, ofrecen una mejor relación de compresión y rendimiento de consultas.
¿Por qué usar Parquet y Feather?
Principales ventajas del formato de almacenamiento en columnas:
| Característica | CSV | Parquet | Feather |
|---|---|---|---|
| Formato de almacenamiento | Por filas | Por columnas | Por columnas |
| Velocidad de lectura | Lento | Muy rápida | Extremadamente rápida |
| Velocidad de escritura | Medio | Rápido | Extremadamente rápida |
| Tasa de compresión | bajo | Alto | Medio |
| Soporte entre lenguajes | Universal | Java/Python/R | Python/R |
Parquet es un proyecto de la Fundación Apache, ampliamente utilizado en el ecosistema de big data (Hadoop, Spark, DuckDB, etc.). Feather es la implementación nativa del proyecto Arrow, centrada en una velocidad de lectura/escritura extrema.
Operaciones con archivos Parquet
Instalar dependencias
pip install pyarrow fastparquet
PyArrow y FastParquet son dos implementaciones de Parquet en Python; PyArrow es la opción predeterminada y FastParquet es más rápido en algunos escenarios.
Leer archivos Parquet
Ejemplo
# Leer archivo Parquet (por defecto usa pyarrow)
df = pd.read_parquet("data.parquet")
# Especificar el uso de un motor concreto
df = pd.read_parquet("data.parquet", engine="pyarrow")
df = pd.read_parquet("data.parquet", engine="fastparquet")
# Leer archivo Parquet remoto
df = pd.read_parquet("s3://bucket/data.parquet")
# Leer solo algunas columnas del archivo (proyección de columnas, mejora el rendimiento)
df = pd.read_parquet("data.parquet", columns=["name", "age", "city"])
print(df.head())
Escribir archivos Parquet
Ejemplo
# Preparar datos de prueba
df = pd.DataFrame({
"id": range(1, 10001),
"name": ["Usuario" + str(i) for i in range(1, 10001)],
"age": [20, 25, 30, 35] * 2500,
"city": ["Pekín", "Shanghái", "Cantón", "Shenzhen"] * 2500,
"score": [round(i * 0.1, 2) for i in range(1, 10001)]
})
# Escribir archivo Parquet (por defecto usa el motor pyarrow)
df.to_parquet("data.parquet", index=False)
# Especificar método de compresión (snappy es rápido, gzip tiene mayor tasa de compresión)
df.to_parquet("data_snappy.parquet", compression="snappy", index=False)
df.to_parquet("data_gzip.parquet", compression="gzip", index=False)
df.to_parquet("data_none.parquet", compression=None, index=False) # Sin compresión
# Ver el tamaño del archivo
import os
print("Comparación de tamaños de archivo:")
print(f"CSV original estimado: {len(df) * 50 / 1024 / 1024:.2f} MB")
print(f"Compresión snappy: {os.path.getsize('data_snappy.parquet') / 1024 / 1024:.2f} MB")
print(f"Compresión gzip: {os.path.getsize('data_gzip.parquet') / 1024 / 1024:.2f} MB")
print(f"Sin compresión: {os.path.getsize('data_none.parquet') / 1024 / 1024:.2f} MB")
Usar el motor rápido de Parquet
Ejemplo
import time
# Probar el rendimiento de escritura de diferentes motores
df = pd.DataFrame({
"id": range(1, 100001),
"value": range(1, 100001)
})
# Escritura con motor pyarrow
start = time.time()
df.to_parquet("test_pyarrow.parquet", engine="pyarrow", compression="snappy")
print(f"Tiempo de escritura pyarrow: {time.time() - start:.3f}s")
# Escritura con motor fastparquet
start = time.time()
df.to_parquet("test_fastparquet.parquet", engine="fastparquet", compression="snappy")
print(f"Tiempo de escritura fastparquet: {time.time() - start:.3f}s")
Operaciones con archivos Feather
Feather es la implementación en Python del proyecto Arrow, centrada en la velocidad extrema de lectura/escritura en memoria.
Instalar dependencias
pip install pyarrow
Leer archivos Feather
Ejemplo
# Leer archivo Feather
df = pd.read_feather("data.feather")
# Leer archivo Feather versión v2 (más universal)
df = pd.read_feather("data.feather", version="2.0")
# Leer ciertas columnas
df = pd.read_feather("data.feather", columns=["name", "age"])
print(df.head())
Escribir archivos Feather
Ejemplo
# Preparar datos de prueba
df = pd.DataFrame({
"id": range(1, 10001),
"name": ["Usuario" + str(i) for i in range(1, 10001)],
"value": [round(i * 0.1, 2) for i in range(1, 10001)]
})
# Escribir archivo Feather
df.to_feather("data.feather")
# Compresión LZ4 (más rápida)
df.to_feather("data_lz4.feather", compression="lz4")
# Compresión ZSTD (mayor tasa de compresión)
df.to_feather("data_zstd.feather", compression="zstd")
# Ver el tamaño del archivo
import os
print(f"Sin compresión: {os.path.getsize('data.feather') / 1024:.2f} KB")
print(f"LZ4: {os.path.getsize('data_lz4.feather') / 1024:.2f} KB")
print(f"ZSTD: {os.path.getsize('data_zstd.feather') / 1024:.2f} KB")
Prueba comparativa de rendimiento
Ejemplo
import numpy as np
import time
import os
import tempfile
# Crear datos de prueba
np.random.seed(42)
n_rows = 1000000
df = pd.DataFrame({
"id": range(n_rows),
"category": np.random.choice(["A", "B", "C", "D"], n_rows),
"value": np.random.randn(n_rows),
"flag": np.random.choice([True, False], n_rows),
"date": pd.date_range("2020-01-01", periods=n_rows, freq="1min")
})
# Crear directorio temporal
with tempfile.TemporaryDirectory() as tmpdir:
# Escritura CSV
start = time.time()
df.to_csv(f"{tmpdir}/data.csv", index=False)
csv_write = time.time() - start
start = time.time()
df_csv = pd.read_csv(f"{tmpdir}/data.csv")
csv_read = time.time() - start
# Escritura Parquet
start = time.time()
df.to_parquet(f"{tmpdir}/data.parquet", index=False)
pq_write = time.time() - start
start = time.time()
df_pq = pd.read_parquet(f"{tmpdir}/data.parquet")
pq_read = time.time() - start
# Escritura Feather
start = time.time()
df.to_feather(f"{tmpdir}/data.feather")
feather_write = time.time() - start
start = time.time()
df_feather = pd.read_feather(f"{tmpdir}/data.feather")
feather_read = time.time() - start
# Mostrar resultados
print(f"{'Formato':<10} {'Tiempo escritura':<12} {'Tiempo lectura':<12} {'Tamaño archivo':<12}")
print("-" * 50)
print(f"{'CSV':<10} {csv_write:.3f}s{'':<5} {csv_read:.3f}s{'':<5} {os.path.getsize(f'{tmpdir}/data.csv')/1024/1024:.2f}MB")
print(f"{'Parquet':<10} {pq_write:.3f}s{'':<5} {pq_read:.3f}s{'':<5} {os.path.getsize(f'{tmpdir}/data.parquet')/1024/1024:.2f}MB")
print(f"{'Feather':<10} {feather_write:.3f}s{'':<5} {feather_read:.3f}s{'':<5} {os.path.getsize(f'{tmpdir}/data.feather')/1024/1024:.2f}MB")
Escenarios de uso y recomendaciones de selección
| Escenario | Formato recomendado | Motivo |
|---|---|---|
| Análisis de big data | Parquet | Alta tasa de compresión, consultas por columnas rápidas, ecosistema amplio |
| Transferencia de datos Python/R | Feather | Lectura/escritura extremadamente rápidas, soporte nativo de Arrow |
| Integración con Spark/Hadoop | Parquet | Formato estándar del ecosistema de big data |
| Copia de seguridad/archivo de datos | Parquet | Alta tasa de compresión, admite evolución de esquema |
| Caché de datos temporal | Feather | Lectura/escritura más rápidas |
Preguntas frecuentes
1. Error al leer Parquet
Asegúrate de tener instalado pyarrow o fastparquet:pip install pyarrow
2. Archivo dañado
Al escribir, asegúrate de que los datos se escriban por completo en el disco; se recomienda verificar la legibilidad del archivo después de escribir.
3. Compatibilidad de versiones
Diferentes versiones de Parquet pueden tener problemas de compatibilidad; se recomienda usar una versión fija en el proyecto.
Otras extensiones