Si utiliza Python para obtener datos, probablemente haya experimentado la frustración de esperar minutos hasta que finalice una operación de Pandas.
Al principio, todo parece estar bien, pero a medida que su conjunto de datos crece y sus flujos de trabajo se vuelven más complejos, de repente parece que su computadora portátil se está preparando para despegar.
Hace un par de meses trabajé en un proyecto que analizaba transacciones de comercio electrónico con más de 3 millones de filas de datos.
Fue una experiencia bastante interesante, pero la mayor parte del tiempo vi operaciones grupales simples que normalmente se ejecutaban en segundos y que de repente se convertían en minutos.
En ese momento, me di cuenta de que Pandas es increíble, pero no siempre es suficiente.
Este artículo explora alternativas modernas a Pandas, incluidos Polars y DuckDB, y examina cómo pueden simplificar y mejorar el manejo de grandes conjuntos de datos.
Para mayor claridad, permítanme ser sincero sobre algunas cosas antes de comenzar.
Este artículo no es una inmersión profunda en la gestión de la memoria de Rust ni una proclamación de que Pandas está obsoleto.
Más bien, es una guía práctica y práctica. Verá ejemplos reales, experiencias personales e información práctica sobre flujos de trabajo que pueden ahorrarle tiempo y cordura.
Por qué los pandas pueden sentirse lentos
Cuando estaba en el proyecto de comercio electrónico, recuerdo haber trabajado con archivos CSV de más de dos gigabytes, y cada filtro o agregación en Pandas a menudo tardaba varios minutos en completarse.
Durante ese tiempo, me quedaba mirando la pantalla, deseando poder tomar un café o disfrutar de algunos episodios de un programa mientras se ejecutaba el código.
Los principales puntos débiles que encontré fueron la velocidad, la memoria y la complejidad del flujo de trabajo.
Todos sabemos que los archivos CSV de gran tamaño consumen enormes cantidades de RAM, a veces más de lo que mi computadora portátil podría manejar cómodamente. Además de eso, encadenar múltiples transformaciones también hizo que el código fuera más difícil de mantener y más lento de ejecutar.
Polars y DuckDB abordan estos desafíos de diferentes maneras.
Polars, integrado en Rust, utiliza la ejecución de subprocesos múltiples para procesar grandes conjuntos de datos de manera eficiente.
DuckDB, por otro lado, está diseñado para análisis y ejecuta consultas SQL sin necesidad de cargar todo en la memoria.
Básicamente, cada uno de ellos tiene su propio superpoder. Polars es el velocista y DuckDB es como el mago de la memoria.
¿Y la mejor parte? Ambos se integran perfectamente con Python, lo que le permite mejorar sus flujos de trabajo sin tener que reescribirlos por completo.
Configurando su entorno
Antes de comenzar a codificar, asegúrese de que su entorno esté listo. Para mantener la coherencia, utilicé Pandas 2.2.0, Polars 0.20.0 y DuckDB 1.9.0.
Fijar versiones puede ahorrarle dolores de cabeza al seguir tutoriales o compartir código.
pip instalar pandas==2.2.0 polares==0.20.0 duckdb==1.9.0
En Python, importe las bibliotecas:
importar pandas como pd importar polares como pl importar duckdb importar advertencias advertencias.filterwarnings (“ignorar”)
Por ejemplo, usaré un conjunto de datos de ventas de comercio electrónico con columnas como ID de pedido, ID de producto, región, país, ingresos y fecha. Puede descargar conjuntos de datos similares de Kaggle o generar datos sintéticos.
Cargando datos
La carga de datos de manera eficiente marca la pauta para el resto de su flujo de trabajo. Recuerdo un proyecto en el que el archivo CSV tenía casi 5 millones de filas.
Pandas lo manejó, pero los tiempos de carga fueron largos y las repetidas recargas durante las pruebas fueron dolorosas.
Fue uno de esos momentos en los que desearías que tu computadora portátil tuviera un botón de “avance rápido”.
Cambiar a Polars y DuckDB mejoró todo por completo y, de repente, pude acceder y manipular los datos casi instantáneamente, lo que honestamente hizo que los procesos de prueba e iteración fueran mucho más agradables.
Con pandas:
df_pd = pd.read_csv(“ventas.csv”) print(df_pd.head(3))
Con polares:
df_pl = pl.read_csv(“ventas.csv”) print(df_pl.head(3))
Con DuckDB:
con = duckdb.connect() df_duck = con.execute(“SELECT * FROM ‘sales.csv'”).df() print(df_duck.head(3))
DuckDB puede consultar archivos CSV directamente sin cargar todos los conjuntos de datos en la memoria, lo que facilita mucho el trabajo con archivos grandes.
Filtrar datos
El problema aquí es que el filtrado en Pandas puede ser lento cuando se trata de millones de filas. Una vez tuve que analizar las transacciones europeas en un conjunto de datos de ventas masivo. Pandas tardó unos minutos, lo que ralentizó mi análisis.
Con pandas:
filtrado_pd = df_pd[df_pd.region == “Europe”]
Polars es más rápido y puede procesar múltiples filtros de manera eficiente:
filtered_pl = df_pl.filter(pl.col(“región”) == “Europa”)
DuckDB usa sintaxis SQL:
filtered_duck = con.execute(“”” SELECT * FROM ‘sales.csv’ WHERE región = ‘Europa’ “””).df()
Ahora puede filtrar grandes conjuntos de datos en segundos en lugar de minutos, lo que le deja más tiempo para centrarse en la información que realmente importa.
Agregando grandes conjuntos de datos rápidamente
La agregación es a menudo donde los pandas comienzan a sentirse lentos. Imagine calcular los ingresos totales por país para un informe de marketing.
En pandas:
agg_pd = df_pd.groupby(“país”)[“revenue”].sum().reset_index()
En polares:
agg_pl = df_pl.groupby(“país”).agg(pl.col(“ingresos”).sum())
En DuckDB:
agg_duck = con.execute(“”” SELECCIONE país, SUMA(ingresos) COMO ingresos_totales DESDE ‘sales.csv’ GRUPO POR país “””).df()
Recuerdo haber ejecutado esta agregación en un conjunto de datos de 10 millones de filas. En Pandas, tomó casi media hora. Los polares completaron la misma operación en menos de un minuto.
La sensación de alivio fue casi como terminar un maratón y darme cuenta de que las piernas aún funcionan.
Unir conjuntos de datos a escala
Unir conjuntos de datos es una de esas cosas que suena simple hasta que estás metido hasta las rodillas en los datos.
En proyectos reales, sus datos generalmente se encuentran en múltiples fuentes, por lo que debe combinarlos usando columnas compartidas como ID de clientes.
Aprendí esto de la manera más difícil mientras trabajaba en un proyecto que requería combinar millones de pedidos de clientes con un conjunto de datos demográficos igualmente grande.
Cada archivo era lo suficientemente grande por sí solo, pero fusionarlos era como intentar juntar dos piezas de un rompecabezas mientras tu computadora portátil pedía clemencia.
Los pandas tardaron tanto que comencé a cronometrar las uniones de la misma manera que la gente mide el tiempo que tardan las palomitas de maíz en el microondas en terminar.
Spoiler: las palomitas de maíz siempre ganaron.
Polars y DuckDB me dieron una salida.
Con pandas:
fusionado_pd = df_pd.merge(pop_df_pd, en=”país”, cómo=”izquierda”)
Polares:
fusionado_pl = df_pl.join(pop_df_pl, en=”país”, cómo=”izquierda”)
PatoDB:
merged_duck = con.execute(“”” SELECT * FROM ‘sales.csv’ s LEFT JOIN ‘pop.csv’ p USING (país) “””).df()
Las uniones en grandes conjuntos de datos que solían congelar su flujo de trabajo ahora se ejecutan sin problemas y de manera eficiente.
Evaluación perezosa en polares
Una cosa que no aprecié al principio de mi viaje hacia la ciencia de datos fue cuánto tiempo se pierde al ejecutar transformaciones línea por línea.
Polars aborda esto de manera diferente.
se utiliza una técnica llamada evaluación diferida, que esencialmente espera hasta que haya terminado de definir sus transformaciones antes de ejecutar cualquier operación.
Examina todo el proceso, determina la ruta más eficiente y ejecuta todo simultáneamente.
Es como tener un amigo que escucha todo el pedido antes de ir a la cocina, en lugar de uno que toma cada instrucción por separado y sigue yendo y viniendo.
Este artículo de TDS explica en profundidad la evaluación diferida.
Así es como se ve el flujo:
Pandas:
gl = gl[df[“amount”] > 100]df = df.groupby(“segmento”).agg({“cantidad”: “media”}) df = df.sort_values(“cantidad”)
Modo perezoso de Polars:
importar polares como pl df_lazy = ( pl.scan_csv(“sales.csv”) .filter(pl.col(“cantidad”) > 100) .groupby(“segmento”) .agg(pl.col(“cantidad”).mean()) .sort(“cantidad”) ) resultado = df_lazy.collect()
La primera vez que utilicé el modo diferido, me resultó extraño no ver resultados instantáneos. Pero una vez que ejecuté el .collect() final, la diferencia de velocidad fue obvia.
La evaluación diferida no resolverá mágicamente todos los problemas de rendimiento, pero aporta un nivel de eficiencia para el que Pandas no fue diseñado.
Conclusión y conclusiones
Trabajar con grandes conjuntos de datos no tiene por qué ser como luchar con sus herramientas.
El uso de Polars y DuckDB me mostró que el problema no siempre fueron los datos. A veces, era la herramienta que estaba usando para manejarlo.
Si hay algo que aprenderás de este tutorial, que sea esto: no tienes que abandonar Pandas, pero puedes buscar algo mejor cuando tus conjuntos de datos comiencen a superar sus límites.
Polars le brinda velocidad y una ejecución más inteligente, luego DuckDB le permite consultar archivos enormes como si fueran pequeños. Juntos, hacen que trabajar con una gran cantidad de datos parezca más manejable y menos agotador.
Si desea profundizar en las ideas exploradas en este tutorial, la documentación oficial de Polars y DuckDB son buenos lugares para comenzar.