Curso
Los archivos CSV son pilares esenciales en el tratamiento y análisis de datos. Casi todos los profesionales de los datos, desde los ingenieros de datos intermedios y los científicos de datos hasta los programadores que utilizan PySpark, tratan con archivos CSV en algún momento. Sin embargo, a medida que los conjuntos de datos crecen de megabytes a gigabytes, o incluso a terabytes y más allá, las herramientas simples y sencillas como Pandas o las bibliotecas estándar de Python tienen dificultades para manejar la carga. Aquí es donde Apache Spark y PySpark cobran importancia para gestionar archivos CSV a gran escala en entornos informáticos distribuidos.
Este artículo te enseñará todo lo que necesitas saber para leer archivos CSV grandes con PySpark.
Asegúrate de que tienes PySpark instalado y de que estás familiarizado con los conceptos básicos siguiendo nuestro tutorial Introducción a PySpark.
¿Qué es leer CSV en PySpark?
PySpark permite leer archivos CSV en DataFrames distribuidos. Los DataFrames de PySpark se parecen mucho a los DataFrames de Pandas, por lo que ofrecen una interfaz familiar. Sin embargo, bajo la superficie, los DataFrames de PySpark distribuyen el cálculo y el almacenamiento entre varios nodos, ofreciendo un rendimiento excepcional para conjuntos de datos masivos.
PySpark ofrece ventajas convincentes para archivos CSV de gran tamaño, como:
- Carga de datos distribuida,
- Tratamiento robusto de los valores nulos,
- Flexibilidad en la definición del esquema, y
- Formas sencillas de gestionar archivos CSV múltiples o comprimidos.
Sin embargo, surgen retos comunes, como manejar eficazmente las cabeceras, deducir o especificar con precisión los esquemas y gestionar los registros malformados o incoherentes. Sigue leyendo para descubrir cómo afrontar todos estos retos.
La lectura de archivos CSV en PySpark es uno de los temas que debes comprender para superar con éxito una entrevista en PySpark. Nuestro Top 36 de Preguntas y Respuestas de Entrevistas PySpark para 2025 proporciona una guía completa de preguntas y respuestas de entrevistas PySpark, cubriendo temas desde conceptos básicos hasta técnicas avanzadas y estrategias de optimización.
Fundamentos de la lectura de archivos CSV en PySpark
La lectura de datos CSV es a menudo uno de los pasos iniciales y más críticos en los flujos de trabajo de PySpark, formando la base para las transformaciones posteriores, el análisis exploratorio y las tareas de machine learning. Hacer bien este paso garantiza un procesamiento de datos más limpio y un mejor rendimiento posterior.
Marco conceptual
PySpark lee archivos CSV dentro del modelo distribuido de Spark. En lugar de leer los datos CSV completamente en memoria en una sola máquina, Spark divide las tareas de datos grandes en varios nodos de clúster. El optimizador Catalyst incorporado en Spark mejora aún más el rendimiento al ejecutar de forma eficiente las operaciones subyacentes necesarias durante la ingestión de CSV.
Sintaxis de lectura del núcleo
La forma más sencilla de leer archivos CSV es mediante las funciones integradas de Spark:
spark.read.csv("file_path", header=True, inferSchema=True)
O explícitamente:
spark.read.format("csv").option("header", "True").load("file_path")
Los parámetros clave son:
file_path
- ubicación de los archivos CSV.header
- establece los nombres de las columnas a partir de las cabeceras del CSV siTrue
.inferSchema
- infiere automáticamente los tipos de datos de las columnas.delimiter
- carácter que separa las columnas; por defecto es la coma.
Nuestro tutorial Aprende PySpark desde cero en 2025 profundiza en los fundamentos de PySpark y en cómo aprenderlo.
Lectura de archivos CSV: Opciones y configuraciones
PySpark proporciona amplias opciones que dan un control granular sobre el proceso de lectura de CSV.
Inferencia de encabezados y esquemas
Configurando header=True
se indica a Spark que utilice la primera línea del CSV como nombres de columna.
inferSchema=True
permite a Spark adivinar automáticamente los tipos de columna escaneando tus datos:
spark.read.csv("customers.csv", header=True, inferSchema=True)
Aunque la inferencia de esquemas es conveniente y eficaz inicialmente, los grandes conjuntos de datos sufren una reducción del rendimiento, ya que Spark realiza pasadas repetidas sobre los datos para determinar los tipos de datos.
Especificación personalizada del esquema
Definir explícitamente tu esquema mejora significativamente el rendimiento al eliminar los repetidos escaneos de datos de Spark. Un esquema definido comunica por adelantado los nombres y tipos de las columnas.
He aquí cómo definir un esquema personalizado en PySpark:
from pyspark.sql.types import StructType, StructField, StringType, IntegerType, DoubleType
schema = StructType([
StructField("user_id", IntegerType(), True),
StructField("name", StringType(), True),
StructField("score", DoubleType(), True),
])
df = spark.read.csv("customers.csv", schema=schema, header=True)
A continuación, vamos a explorar el manejo de los delimitadores en PySpark al leer archivos CSV.
Manejo de delimitadores y caracteres especiales
Muchos archivos CSV utilizan delimitadores distintos de la coma, como tubos o tabuladores. PySpark permite especificar el delimitador explícitamente:
spark.read.csv("customers.csv", header=True, delimiter="|")
Además, también se pueden configurar caracteres de escape y comillas para manejar escenarios de caracteres especiales:
spark.read.csv("data.csv", header=True, escape='\"', quote='"')
Gestión de valores nulos y ausentes
Los datos CSV del mundo real suelen contener incoherencias o registros incompletos. PySpark simplifica el manejo de los valores nulos traduciendo los marcadores de posición personalizados a valores nulos:
spark.read.csv("customers.csv", header=True, schema=schema, nullValue="NA")
Esto aclara los valores nulos, reduciendo drásticamente la limpieza manual de datos posterior.
Exploremos otras estrategias para tratar los valores nulos.
Puedes decidir filtrar los valores nulos:
# Filter rows where Age is not null
df_filtered = df.filter(df["Age"].isNotNull())
df_filtered.show()
Filtra el DataFrame para incluir sólo las filas en las que la columna Age
no sea nula. El resultado debería ser así:
+---+-----+---+------+
| ID| Name|Age|Salary|
+---+-----+---+------+
| 1| John| 25| 50000|
| 3| Bob| 30| NULL|
| 4|Carol| 28| 55000|
+---+-----+---+------+
La otra estrategia es rellenar los valores nulos:
# Replace null values in Age and Salary with default values
df_filled = df.na.fill({"Age": 0, "Salary": 0})
df_filled.show()
El resultado será así:
+---+-----+---+------+
| ID| Name|Age|Salary|
+---+-----+---+------+
| 1| John| 25| 50000|
| 2|Alice| 0| 60000|
| 3| Bob| 30| 0|
| 4|Carol| 28| 55000|
| 5|David| 0| 48000|
+---+-----+---+------+
Lectura de varios archivos y directorios
PySpark destaca en la gestión de grandes conjuntos de datos con múltiples archivos. En lugar de cargar y combinar manualmente archivos de un directorio de forma secuencial, PySpark admite patrones comodín para una carga masiva rápida y eficiente:
spark.read.csv("/data/sales/*.csv", header=True, schema=schema)
Esto agrega de forma efectiva numerosos archivos CSV en un DataFrame en una sola operación racionalizada.
Una vez cargados los datos en PySpark, los pasos siguientes incluyen la manipulación, la ingeniería de características y la construcción de modelos de machine learning. Nuestro curso Feature Engineering with PySpark cubre estos conceptos en profundidad.
Técnicas de optimización para la lectura eficiente de CSV
Cuando se manejan datos CSV a gran escala, es crucial aprovechar las estrategias de optimización de PySpark.
Estrategias de partición
El particionamiento influye mucho en el rendimiento, al distribuir uniformemente los datos entre los nodos del clúster. Spark permite controlar explícitamente el tamaño y el número de particiones durante la ingesta de datos para ayudar a acelerar las operaciones posteriores:
df = spark.read.csv("data.csv", header=True, schema=schema).repartition(20)
.repartition(20)
divide el DataFrame en 20 particiones en tu clúster Spark. Como Spark procesa los datos en trozos, tener más particiones puede:
- Mejorar el paralelismo
- Equilibra la carga de trabajo en el clúster
- Acelera las transformaciones y las escrituras
Si estás funcionando en un clúster con muchos núcleos, esto ayuda a aprovecharlos al máximo. Pero puedes ralentizar las cosas si te pasas (digamos, 1000 particiones en un conjunto de datos pequeño).
Descubre más funciones Spark como repartition
con nuestra PySpark Cheat Sheet: Spark en Python. Explica en detalle cómo inicializar Spark en Python, cargar datos, ordenar y reparticionar.
Caché y persistencia
Si tu flujo de trabajo implica acceder repetidamente al mismo conjunto de datos después de la ingestión, almacenar en caché tu DataFrame en memoria o en disco puede aumentar el rendimiento de forma significativa:
df.cache()
Sin embargo, recuerda que el almacenamiento en caché requiere suficientes recursos del sistema; equilibra siempre el uso de memoria con las ganancias de rendimiento.
Evaluación perezosa y acciones desencadenantes
PySpark se basa en un modelo de evaluación perezoso: las operaciones de DataFrame transforman los planes en lugar de ejecutarse inmediatamente. La lectura real del archivo sólo se ejecuta cuando es necesario, activada por comandos como show()
, count()
, o collect()
:
# no reading yet
df = spark.read.csv("data.csv", header=True, schema=schema)
# actual read triggered here
df.show(5)
Casos de uso y consideraciones avanzadas
Exploremos situaciones más complejas que puedes encontrarte al leer archivos CSV:
Lectura de archivos CSV comprimidos
Spark gestiona eficazmente archivos CSV comprimidos como gz
o .bz2
de forma transparente y sin configuraciones adicionales:
spark.read.csv("logs.csv.gz", header=True, schema=schema)
Tratamiento de registros malformados
Los conjuntos de datos CSV pueden contener líneas mal formadas. PySpark ofrece múltiples opciones para ayudarte a gestionar con elegancia los errores o registros malformados:
mode="PERMISSIVE"
(por defecto): incluye filas malformadas con columnas rellenas de nulos.mode="DROPMALFORMED
: omite silenciosamente los registros mal formados. Este modo no es compatible con las funciones integradas CSV.mode="FAILFAST"
lanza una excepción al encontrar un registro malformado.
spark.read.csv("data.csv", header=True, schema=schema, mode="FAILFAST")
Configuración regional y de codificación
A veces, los datos CSV utilizan codificaciones no estándar. PySpark maneja fácilmente diferentes codificaciones mediante el parámetro encoding:
spark.read.csv("data_utf8.csv", header=True, encoding="UTF-8")
Las codificaciones admitidas son, US-ASCII
, ISO-8859-1
, UTF-8
, UTF-16BE
, UTF-16LE
, y UTF-16
.
Buenas prácticas y errores comunes
Aquí tienes algunas buenas prácticas que debes tener en cuenta al leer archivos CSV con Spark:
- Especifica explícitamente el esquema siempre que se conozca la estructura del conjunto de datos.
- Controla la partición para distribuir eficazmente la carga de trabajo.
- Cachea estratégicamente los DataFrames a los que se accede con frecuencia.
- Desencadena acciones de lectura intencionadamente, teniendo en cuenta la evaluación perezosa.
Asegúrate de evitarlo:
- Configurar
header=False
para CSV con filas de cabecera. - Basarse únicamente en
inferSchema
en conjuntos de datos grandes o a los que se accede repetidamente. - Ignorar delimitadores críticos o ajustes de codificación.
Conclusión
Comprender y aprovechar adecuadamente las potentes capacidades de ingestión de CSV de PySpark es esencial para un procesamiento eficaz de big data. Con una especificación clara del esquema, la gestión de formatos nulos personalizados, el uso de particiones eficaces y la gestión de escenarios de archivos comprimidos o múltiples, tu flujo de trabajo se vuelve más ágil y eficaz.
Recuerda que, aunque PySpark proporciona enormes ventajas para tareas de datos a gran escala, herramientas más sencillas como Pandas pueden seguir siendo suficientes para conjuntos de datos pequeños. Utiliza PySpark cuando trabajes con datos que superen las capacidades de una sola máquina, y ten siempre en cuenta sus ventajas de computación distribuida.
Para explorar PySpark más a fondo, echa un vistazo a nuestros cursos Spark en profundidad, incluyendo:
PySpark Leer CSV Preguntas frecuentes
¿Cuál es la mejor forma de leer archivos CSV grandes en PySpark?
La mejor práctica es especificar un esquema personalizado utilizando StructType en lugar de confiar en inferSchema. Este método mejora el rendimiento al evitar el escaneo repetido de datos.
¿Puede PySpark manejar archivos CSV con delimitadores diferentes?
Sí. Puedes establecer un delimitador personalizado utilizando la opción delimitador en spark.read.csv()
. Por ejemplo, utiliza delimiter="|" para valores separados por tuberías.
¿Cómo leo varios archivos CSV a la vez en un directorio?
Puedes utilizar una ruta comodín, como spark.read.csv("/data/*.csv", ...)
, para cargar varios archivos a la vez en un único DataFrame.
¿Qué hace `mode="DROPMALFORMED"` al leer CSVs?
Indica a Spark que omita e ignore los registros malformados del archivo CSV en lugar de incluirlos o provocar fallos.
¿Puede PySpark leer archivos CSV comprimidos como `.gz` o `.bz2`?
Sí. PySpark descomprime y lee automáticamente los archivos CSV comprimidos sin necesidad de configuración adicional cuando proporcionas la ruta correcta del archivo.
