(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo leer y escribir Parquet en PySpark: paso a paso

João Barros 11 de July de 2026 4 min de lectura

Parquet es el formato de archivo más usado en proyectos de datos con Spark: guarda la información por columnas, ocupa mucho menos espacio que un CSV y permite leer solo las columnas que necesitas. Saber leer y escribir Parquet en PySpark es, por eso, uno de los pasos esenciales para construir pipelines rápidos y baratos en un Lakehouse. Vamos a hacerlo con ejemplos mínimos que puedes copiar y ejecutar ya.

Requisitos previos

  • Un entorno con PySpark: Databricks, Microsoft Fabric, Azure Synapse o pip install pyspark en tu equipo.
  • Python 3.8 o superior y Java 11 (solo necesario si ejecutas Spark en local).
  • Nociones básicas de DataFrames: select, filter y show.
  • Una carpeta donde puedas escribir archivos (disco local o almacenamiento cloud).

Paso 1: Crear la sesión de Spark y un DataFrame de ejemplo

Para escribir Parquet en PySpark necesitas una SparkSession y datos. En Databricks, Fabric o Synapse la variable spark ya existe — en ese caso salta las dos primeras líneas.

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("parquet-demo").getOrCreate()

dados = [
    ("Ana", "Lisboa", 2025, 1200.0),
    ("Bruno", "Porto", 2025, 890.5),
    ("Carla", "Lisboa", 2026, 1540.0),
    ("Diogo", "Faro", 2026, 730.25),
]
vendas = spark.createDataFrame(dados, ["vendedor", "cidade", "ano", "valor"])
vendas.show()

Paso 2: Escribir el DataFrame en Parquet

La escritura se hace con write.parquet(). Hay un detalle que confunde a mucha gente al principio: la ruta que indicas no es un archivo, es una carpeta. Spark crea dentro varios archivos .parquet, uno por cada partición que tiene en memoria, más algunos archivos de control.

vendas.write.mode("overwrite").parquet("/tmp/vendas_parquet")

mode define qué ocurre cuando la carpeta ya existe:

  • overwrite: borra el contenido anterior y vuelve a escribir.
  • append: añade nuevos archivos a los que ya están.
  • error (por defecto): falla con el error path already exists.
  • ignore: no escribe nada si la carpeta ya existe.

Paso 3: Particionar los datos con partitionBy

Si casi siempre filtras por la misma columna (año, país, fecha), guarda los datos particionados. Spark crea una subcarpeta por valor y, al leer, ignora las carpetas que no interesan — esto se llama partition pruning y es lo que hace que las consultas sean rápidas.

(vendas.write
    .mode("overwrite")
    .partitionBy("ano")
    .parquet("/tmp/vendas_por_ano"))

En disco queda así:

/tmp/vendas_por_ano/ano=2025/part-00000-....snappy.parquet
/tmp/vendas_por_ano/ano=2026/part-00000-....snappy.parquet
Consejo: particiona por columnas con pocos valores distintos (decenas o centenas). Particionar por una columna con miles de valores crea miles de archivos diminutos y lo hace todo más lento, no más rápido.

Paso 4: Leer archivos Parquet

Para leer basta con apuntar a la carpeta. A diferencia del CSV, no necesitas declarar el schema ni usar inferSchema: los nombres y los tipos de las columnas están guardados dentro del propio archivo Parquet.

df = spark.read.parquet("/tmp/vendas_por_ano")
df.printSchema()

# apenas as linhas de 2026: o Spark lê só a subpasta ano=2026
df_2026 = df.filter(df.ano == 2026)
df_2026.show()

Como Parquet es columnar, también puedes pedir solo las columnas que necesitas — Spark ni siquiera lee las demás del disco:

df.select("vendedor", "valor").show()

Paso 5: Compresión y número de archivos

Por defecto Spark comprime con snappy, el mejor equilibrio entre tamaño y velocidad. Si necesitas archivos aún más pequeños, usa gzip. Y cuando el resultado es pequeño, junta todo en un único archivo con coalesce(1) para evitar el problema de los small files.

(vendas
    .coalesce(1)
    .write
    .mode("overwrite")
    .option("compression", "gzip")
    .parquet("/tmp/vendas_pequeno"))

Verificar el resultado

Vuelve a leer lo que escribiste y comprueba tres cosas: el número de filas, los tipos de las columnas y las particiones creadas.

lido = spark.read.parquet("/tmp/vendas_por_ano")

print(lido.count())               # deve devolver 4
lido.printSchema()                # valor: double, ano: integer
lido.groupBy("ano").count().show()  # 2 linhas por ano

Si count() devuelve 4 y el schema muestra valor como double, todo está bien — los tipos sobrevivieron al viaje al disco, algo que no ocurre con CSV. El error más común en esta fase es Unable to infer schema for Parquet: casi siempre significa que la ruta es incorrecta o que la carpeta está vacía.

Conclusión

Con write.parquet(), partitionBy() y read.parquet() ya tienes lo esencial para cambiar tus CSV por un formato que ahorra espacio y tiempo de lectura. El siguiente paso natural es evolucionar a tablas Delta Lake, que añaden transacciones ACID, historial de versiones y MERGE sobre estos mismos archivos Parquet. Antes de eso, haz un experimento: escribe el mismo DataFrame en CSV y en Parquet y compara el tamaño de las carpetas — ¿cuál fue la diferencia en tu caso?