Curso
Si utilizas Python a menudo para análisis de datos, como yo, verás enseguida que leer archivos CSV es una de las tareas más habituales. Sin embargo, a medida que crecen tus datasets, este método puede volverse lento o consumir mucha memoria.
Polars es una biblioteca moderna y rápida de DataFrames para Python, pensada como alternativa de alto rendimiento a Pandas. Gestiona grandes volúmenes de datos con mucha más fluidez que las herramientas tradicionales porque está diseñada para priorizar la velocidad y el bajo uso de memoria.
La función principal de Polars pl.read_csv() ofrece una forma sencilla de cargar archivos CSV en un DataFrame, con opciones integradas para controlar el parseo, los tipos de datos y el uso de memoria.
En esta guía, te mostraré cómo leer archivos CSV, controlar el parseo y trabajar con grandes datasets usando la función pl.read_csv() de Polars. Si estás empezando, echa un vistazo a nuestro curso Introduction to Polars para aprender a manipular datos y extraer insights con Polars.
Uso básico de pl.read_csv()
Antes de seguir, revisa nuestro tutorial de Python Polars para configurar tu entorno.
Ahora, veamos cómo funciona la función pl.read_csv():
# import the module
import polars as pl
# Load CSV into a Polars DataFrame
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv")
# Preview first few rows
print(fuel_data.head())
En el ejemplo anterior, Polars lee el archivo y lo carga en un DataFrame. La función devuelve un DataFrame de Polars, que es una estructura tabular similar a la que obtendrías en pandas.
Por defecto, pl.read_csv():
-
Asume que la primera fila contiene los nombres de las columnas (
has_header=True) -
Infiera automáticamente los tipos de datos de las columnas
-
Usa la coma (
,) como delimitador -
Lee el archivo completo en memoria
Parámetros comunes en pl.read_csv()
Ahora que has visto cómo pl.read_csv() carga los datos, veamos cómo puedes usar los siguientes parámetros para adaptar cómo Polars interpreta tu archivo.
Ruta y origen del archivo
Polars te permite cargar datos desde distintas fuentes. Puedes pasar una ruta local como cadena, un objeto Pathlib o incluso una URL. Por ejemplo, el siguiente código lee desde la web un archivo CSV grande con el PIB de distintos países a lo largo de varios años.
# Reading from a URL
url = "https://raw.githubusercontent.com/datasets/gdp/master/data/gdp.csv"
gdp_data = pl.read_csv(url)
Delimitadores y separadores
No todos los CSV usan comas. Puedes usar el argumento separator para manejar tabuladores, puntos y coma, barras verticales u otros caracteres. El ejemplo de abajo muestra cómo especificar separadores al leer archivos.
# Reading a Semicolon-separated file
sales_data = pl.read_csv("2024_sales.csv", separator=";")
# Reading a Tab-separated file (TSV)
orders_data = pl.read_csv("all_orders.tsv", separator="\t")
Gestión del encabezado
Como hemos visto, Polars asume que la primera fila contiene los nombres de las columnas. Si tu archivo no tiene fila de encabezado, usa el parámetro has_header=False como se muestra a continuación. Polars asignará nombres automáticamente como column_1, column_2, column_3, etc.
# Load file without a header
orders_data = pl.read_csv("all_orders.csv", has_header=False)
También puedes renombrar columnas proporcionando los nombres específicos. Por ejemplo:
# Providing specific column names
sales_data = pl.read_csv("sales_April.csv", new_columns=[
"OrderDate", "OrderNumber", "ProductKey", "SalespersonKey", "Salesperson"])
Codificación
Los archivos CSV pueden usar distintas codificaciones de texto. Si ves caracteres extraños o errores, especifica la codificación:
# Load CSV into a Polars DataFrame
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv", encoding="utf8")
Otras opciones comunes son ”latin1” y ”utf8-lossy”, que gestionan adecuadamente los caracteres no válidos.
Cómo seleccionar columnas al leer CSV en Polars
Cuando trabajas con archivos CSV grandes, a menudo no necesitas todas las columnas. Polars te permite cargar solo las columnas que necesitas usando el parámetro columns.
# Load only specific columns
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv",
columns=["YEAR", "MAKE", "MODEL"]
)
Al seleccionar las columnas necesarias durante la carga, reduces el uso de memoria al evitar datos innecesarios. Este método también acelera la lectura y mejora el rendimiento general del pipeline.
Cómo gestionar los tipos de datos (esquema) en CSV con Polars
Polars es una biblioteca fuertemente tipada, lo que significa que cada columna debe tener un tipo de dato consistente, por ejemplo, todos enteros o todas cadenas.
Inferencia automática de tipos
Por defecto, Polars inspecciona tus datos y determina automáticamente los tipos de las columnas. Este método funciona bien en la mayoría de los casos, pero a veces puede interpretar mal algunas columnas, como tratar identificadores como enteros en lugar de cadenas.
Especificar el esquema manualmente
Si quieres coherencia en tu DataFrame, conviene especificar el esquema de datos manualmente. Así garantizas consistencia entre múltiples archivos y evitas errores de tipos en procesos posteriores.
En la mayoría de los casos, usa schema_overrides para definir el tipo de datos de columnas concretas y permitir que Polars infiera el resto.
import polars as pl
# Manually overriding specific data types
empl_data = pl.read_csv(
"all_employees.csv",
schema_overrides={
"id": pl.Int64,
"name": pl.String,
"age": pl.Int64,
"salary": pl.Float64
}
)
O usa schema para definir toda la estructura del DataFrame.
# Manually define the full schema
empl_data = pl.read_csv(
"all_employees.csv",
schema={
"id": pl.Int64,
"name": pl.String,
"age": pl.Int64,
"salary": pl.Float64
}
)
Cómo gestionar los valores ausentes en CSV con Polars
Por defecto, Polars detecta automáticamente estos valores ausentes y los representa como null. A veces, los valores ausentes aparecen como cadenas específicas, como ”NA”, ”N/A” o ”missing”. Puedes definirlas con null_values para tratarlas como null.
# Treating "N/A" and "EMPTY" as nulls
survey_data = pl.read_csv(
"survey_results.csv",
null_values=["N/A", "EMPTY", "null"]
)
Al gestionar bien los valores ausentes, aseguras tipos de datos consistentes y evitas cálculos incorrectos, reduciendo errores durante el análisis y el modelado.
Lectura de archivos CSV grandes en Polars
Cuando trabajas con datasets grandes que superan tu RAM disponible, Polars brilla al procesar los datos sin cargar el archivo completo de una vez.
Carga diferida con scan_csv()
En lugar de cargar los datos en memoria inmediatamente como read_csv(), Polars ofrece una alternativa perezosa, scan_csv(), que construye un plan de consulta optimizado y ejecuta solo las operaciones necesarias.
En el ejemplo siguiente, pl.scan_csv escanea el archivo CSV sin cargarlo, construye una consulta para obtener únicamente las columnas “YEAR”, “MAKE” y “MODEL” donde la marca es “ACURA”, y después ejecuta esa consulta. Así, solo se carga en memoria el fragmento filtrado, no el archivo completo.
# Lazily reference the file (no data loaded yet)
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv")
fuel_consumption_filtered = fuel_consumption.select(
["YEAR", "MAKE", "MODEL"]).filter(pl.col("MAKE") == "ACURA")
# Execute the query and load only the required data
fuel_consumption_acura = fuel_consumption_filtered.collect()
Te recomiendo usar scan_csv() cuando:
- Trabajas con archivos grandes que no caben cómodamente en memoria
- Aplicas varias transformaciones, como filtrar, seleccionar y agregar datos
- Quieres optimización de la consulta antes de ejecutarla
Streaming y eficiencia de memoria
Polars también permite procesar datos en streaming por bloques, manteniendo constante el pico de memoria independientemente del tamaño del archivo.
Para archivos CSV grandes, empieza con scan_csv() para crear una consulta perezosa. El archivo no se carga por completo cuando se llama a scan_csv().
# Read data in chunks
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv",
low_memory=True)
Dado que el método anterior sigue usando read_csv, la mejor estrategia es combinar la ejecución perezosa con el streaming.
En el ejemplo de abajo, Polars procesa el archivo en una canalización, fila a fila en lotes, manteniendo en memoria solo las filas filtradas (donde “CYLINDERS” > 3) en cada momento.
# Lazily reference the file (no data loaded yet)
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv")
result = fuel_consumption.filter(pl.col("CYLINDERS") > 3)
# Stream execution instead of loading everything at once
fuel_consumption_high = result.collect(engine="streaming")
Ventaja de rendimiento vs. Pandas
En comparación con pandas, Polars suele rendir mejor al leer y procesar CSV, como veremos en la siguiente sección.
Polars read_csv vs Pandas read_csv
La tabla siguiente resume las diferencias entre Polars y Pandas al leer CSV en Python.
|
Aspecto |
Polars |
Pandas |
|
Velocidad |
Más rápido gracias al multithreading y al parseo optimizado |
Más lento con archivos grandes (mayoritariamente monohilo) |
|
Uso de memoria |
Huella más baja; admite ejecución perezosa + streaming |
Carga todo el dataset de forma ansiosa en memoria |
|
Sintaxis |
|
|
|
Modelo de ejecución |
Admite ejecución perezosa ( |
Solo ejecución ansiosa (inmediata) |
|
Optimización |
Optimización de consultas integrada (proyección, filtrado) |
Optimización automática limitada |
|
Mejor caso de uso |
Grandes volúmenes de datos, flujos críticos de rendimiento |
Datasets pequeños, análisis rápidos |
Te recomiendo leer nuestro artículo sobre las diferencias entre Pandas vs. Polars para decidir qué herramienta se ajusta mejor a tus necesidades analíticas.
Leer CSV desde distintas fuentes
Como vimos antes, puedes usar Polars para leer archivos CSV desde varias fuentes. En los ejemplos anteriores te mostré cómo leer CSV desde archivos locales y URLs.
Además, Polars puede manejar automáticamente archivos CSV comprimidos. Por ejemplo, el siguiente código lee datos desde un archivo .gzip.
# Read gzip-compressed CSV
census_data = pl.read_csv("2018_census.csv.gz")
Errores comunes y cómo solucionarlos
Incluso con un motor de alto rendimiento como Polars, pueden surgir incidencias, sobre todo al leer un CSV. Estos son algunos problemas habituales que me he encontrado y cómo resolverlos.
-
Errores de codificación: Puedes ver un error como
UnicodeDecodeError, que indica que el archivo no usa codificación UTF-8, algo común en archivos antiguos o CSV exportados desde ciertas versiones de Excel. Para solucionarlo, establece la codificación apropiada o usa“utf8-lossy”si el archivo tiene caracteres incoherentes o corruptos. -
Problemas con el delimitador: Si tu DataFrame se carga pero todos los datos aparecen en una única columna, Polars no reconoció el separador. Para solucionarlo, especifica el delimitador correcto con el argumento
separator, como punto y coma (;), tabulador (\t) o barra vertical (|). -
Tipos de datos incorrectos: A veces Polars puede inferir mal los tipos, por ejemplo, leer IDs numéricos como cadenas o encontrarse con errores de parseo. En ese caso, usa
schema_overridespara especificar el tipo de columnas concretas. Si quieres definir los tipos de todas las columnas, utilizaschema. También puedes aumentarinfer_schema_lengthpara que Polars examine más filas antes de inferir el esquema. -
Problemas de memoria con archivos grandes: Si tu proceso de Python se cierra al cargar un archivo grande, es que te has quedado sin RAM. Cambia de
read_csv()ascan_csv()para carga perezosa y así reducir el uso de memoria y mejorar el rendimiento. También puedes cargar menos columnas del dataset o usar ejecución en streaming para procesar los datos por bloques.
Conclusión
La función read_csv() de Polars es sencilla de usar, pero lo bastante potente para casos reales. En mi opinión, Polars ofrece una clara ventaja cuando trabajas con datasets en crecimiento.
Como siguiente paso, pásate por nuestro blog sobre el Polars GPU engine para conocer mejor sus aplicaciones. Si quieres ponerte manos a la obra, nuestro Super Bowl Analytics with Polars code-along te ayudará a resolver preguntas analíticas reales, aplicar cálculos y utilizar técnicas básicas de ML en problemas de analítica deportiva.
FAQs
¿Cuál es la diferencia entre read_csv() y scan_csv() en Polars?
read_csv() carga los datos de forma ansiosa en memoria, mientras que scan_csv() usa ejecución perezosa y solo procesa los datos cuando llamas a .collect().
¿Cuándo debería usar scan_csv() en lugar de read_csv()?
Usa scan_csv() para datasets grandes o cuando encadenes transformaciones, ya que optimiza la ejecución y reduce el uso de memoria.
¿Puede Polars leer solo columnas específicas de un archivo CSV?
Sí, usa el parámetro columns=[...] en read_csv() o selecciona columnas en una consulta perezosa con scan_csv().
¿Cómo gestiono los valores ausentes en archivos CSV con Polars?
Polars trata los valores vacíos como null por defecto, y puedes definir marcadores de nulos personalizados con null_values=.
¿Polars admite archivos CSV comprimidos?
Sí, puede leer formatos comprimidos como .gz y .zip sin extraerlos manualmente.
