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

import pandas as pd

# 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

import pandas as pd

# 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 pandas as pd
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

import pandas as pd

# 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

import pandas as pd

# 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 pandas as pd
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