7 trucos de rendimiento de Pandas que todo científico de datos debería conocer

un artículo en el que analicé algunas de las herramientas DataFrame más nuevas en Python, como Polars y DuckDB.

Exploré cómo pueden mejorar el flujo de trabajo de la ciencia de datos y funcionar de manera más efectiva al manejar grandes conjuntos de datos.

Aquí hay un enlace al artículo.

La idea era brindarles a los profesionales de datos una idea de cómo son los “marcos de datos modernos” y cómo estas herramientas podrían remodelar la forma en que trabajamos con los datos.

Pero sucedió algo interesante: por los comentarios que recibí, me di cuenta de que muchos científicos de datos todavía dependen en gran medida de Pandas para la mayor parte de su trabajo diario.

Y entiendo totalmente por qué.

Incluso con todas las nuevas opciones que existen, Pandas sigue siendo la columna vertebral de la ciencia de datos de Python.

Y esto no se basa ni siquiera en unos pocos comentarios.

Una encuesta reciente sobre el estado de la ciencia de datos informa que el 77% de los profesionales utilizan Pandas para la exploración y el procesamiento de datos.

Me gusta pensar en Pandas como ese viejo amigo confiable al que sigues llamando: tal vez no sea el más llamativo, pero sabes que siempre hace el trabajo.

Entonces, si bien las herramientas más nuevas tienen absolutamente sus puntos fuertes, está claro que Pandas no irá a ninguna parte pronto.

Y para muchos de nosotros, el verdadero desafío no es reemplazar Pandas, sino hacerlo más eficiente y un poco menos doloroso cuando trabajamos con conjuntos de datos más grandes.

En este artículo, lo guiaré a través de siete formas prácticas de acelerar sus flujos de trabajo de Pandas. Son fáciles de implementar pero capaces de hacer que su código sea notablemente más rápido.

Configuración y requisitos previos

Antes de comenzar, esto es lo que necesitará. Estoy usando Python 3.10+ y Pandas 2.x en este tutorial. Si tiene una versión anterior, puede actualizarla rápidamente:

instalación de pip –actualizar pandas

Eso es realmente todo lo que necesitas. Un entorno estándar, como Jupyter Notebook, VS Code o Google Colab, funciona bien.

Si ya tiene NumPy instalado, como la mayoría de las personas, todo lo demás en este tutorial debería ejecutarse sin ninguna configuración adicional.

1. Acelere read_csv con valores predeterminados más inteligentes

Recuerdo la primera vez que trabajé con un archivo CSV de 2 GB.

Los ventiladores de mi computadora portátil gritaban, la computadora portátil seguía congelada y yo miraba la barra de progreso, preguntándome si alguna vez terminaría.

Más tarde me di cuenta de que la desaceleración no se debía a Pandas en sí, sino a que le permitía detectar todo automáticamente y cargar las 30 columnas cuando solo necesitaba 6.

Una vez que comencé a especificar tipos de datos y seleccionar solo lo que necesitaba, las cosas se volvieron notablemente más rápidas.

Las tareas que normalmente me tenían mirando una barra de progreso congelada ahora se ejecutaron sin problemas y finalmente sentí que mi computadora portátil estaba de mi lado.

Déjame mostrarte exactamente cómo lo hago.

Especifique los tipos por adelantado

Cuando obligas a Pandas a adivinar tipos de datos, tiene que escanear todo el archivo. Si ya sabe cuáles deberían ser sus columnas, dígalo directamente:

df = pd.read_csv( “sales_data.csv”, dtype={ “store_id”: “int32”, “product_id”: “int32”, “category”: “category” } )

Cargue solo las columnas que necesita

A veces tu CSV tiene docenas de columnas, pero solo te interesan unas pocas. Cargar el resto sólo desperdicia memoria y ralentiza el proceso.

cols_to_use = [“order_id”, “customer_id”, “price”, “quantity”]

df = pd.read_csv(“pedidos.csv”, usecols=cols_to_use)

Utilice tamaño de fragmento para archivos grandes

Para archivos muy grandes que no caben en la memoria, la lectura en fragmentos le permite procesar los datos de forma segura sin bloquear su computadora portátil.

fragmentos = pd.read_csv(“logs.csv”, chunksize=50_000) para fragmento en fragmentos: # procesa cada fragmento según sea necesario

Sencillo, práctico y realmente funciona.

Una vez que haya cargado sus datos de manera eficiente, lo siguiente que lo ralentizará es cómo Pandas los almacena en la memoria.

Incluso si ha cargado solo las columnas que necesita, el uso de tipos de datos ineficientes puede ralentizar silenciosamente sus flujos de trabajo y consumir memoria.

Es por eso que el siguiente truco consiste en elegir los tipos de datos correctos para que sus operaciones de Pandas sean más rápidas y ligeras.

2. Utilice los tipos de datos adecuados para reducir la memoria y acelerar las operaciones

Una de las formas más sencillas de acelerar los flujos de trabajo de Pandas es almacenar datos en el tipo correcto.

Mucha gente se queda con los tipos de objetos predeterminados o float64. Son flexibles, pero créanme, son pesados.

Cambiar a tipos más pequeños o más adecuados puede reducir el uso de memoria y mejorar notablemente el rendimiento.

Convierta números enteros y flotantes a tipos más pequeños

Si una columna no necesita una precisión de 64 bits, la conversión ascendente puede ahorrar memoria:

# Ejemplo de marco de datos df = pd.DataFrame({ “user_id”: [1, 2, 3, 4]”puntaje”: [99.5, 85.0, 72.0, 100.0]
}) # Columnas flotantes y enteras abatidas df[“user_id”] = gl[“user_id”].astype(“int32”) df[“score”] = gl[“score”].astype(“flotador32”)

Usar categoría para cadenas repetidas

Las columnas de cadena con muchos valores repetidos, como nombres de países o categorías de productos, se benefician enormemente al convertirse al tipo de categoría:

df[“country”] = gl[“country”].astype(“categoría”) df[“product_type”] = gl[“product_type”].astype(“categoría”)

Esto ahorra memoria y hace que operaciones como filtrar y agrupar sean notablemente más rápidas.

Verifique el uso de la memoria antes y después

Puedes ver el efecto inmediatamente:

print(df.info(memory_usage=”profundo”))

He visto una caída del uso de la memoria del 50 % o más en conjuntos de datos grandes. Y cuando se utiliza menos memoria, operaciones como el filtrado y las uniones se ejecutan más rápido porque hay menos datos para que Pandas los baraje.

3. Deje de hacer bucles. Comience a vectorizar

Uno de los mayores errores de rendimiento que veo es el uso de bucles de Python o .apply() para operaciones que se pueden vectorizar.

Los bucles son fáciles de escribir, pero Pandas se basa en operaciones vectorizadas que se ejecutan en C internamente y, además, se ejecutan mucho más rápido.

Enfoque lento usando .apply() (o un bucle):

# Ejemplo: agregar 10% de impuesto a los precios df[“price_with_tax”] = gl[“price”].aplicar(lambda x: x * 1.1)

Esto funciona bien en conjuntos de datos pequeños, pero una vez que alcanzas cientos de miles de filas, comienza a rastrearse.

Enfoque vectorizado rápido:

# Operación vectorizada df[“price_with_tax”] = gl[“price”] * 1.1

Eso es todo. Mismo resultado, órdenes de magnitud más rápido.

4. Utilice loc e iloc de la forma correcta

Una vez intenté filtrar un conjunto de datos grande con algo como df[df[“price”] > 100][“category”]. Pandas no solo me lanzó advertencias, sino que el código era más lento de lo que debería haber sido.

Aprendí bastante rápido que la indexación encadenada es confusa e ineficiente; También podría provocar errores sutiles y problemas de rendimiento.

Usar loc e iloc correctamente hace que su código sea más rápido y fácil de leer.

Utilice loc para indexación basada en etiquetas

Cuando desee filtrar filas y seleccionar columnas por nombre, loc es su mejor opción:

# Seleccione filas donde el precio > 100 y solo se filtre la columna ‘categoría’ = df.loc[df[“price”] > 100, “categoría”]

Esto es más seguro y rápido que el encadenamiento y evita el infame SettingWithCopyWarning.

Utilice iloc para indexación basada en posición

Si prefiere trabajar con posiciones de filas y columnas:

# Seleccione las primeras 5 filas y el subconjunto de las primeras 2 columnas = df.iloc[:5, :2]

El uso de estos métodos mantiene su código limpio y eficiente, especialmente cuando realiza tareas o filtrado complejo.

5. Utilice query() para un filtrado más rápido y limpio

Cuando su lógica de filtrado comienza a complicarse, query() puede hacer que las cosas parezcan mucho más manejables.

En lugar de apilar múltiples condiciones booleanas entre corchetes, query() le permite escribir filtros en una sintaxis más limpia, casi similar a la de SQL.

Y en muchos casos, se ejecuta más rápido porque Pandas puede optimizar la expresión internamente.

# Filtrado más legible usando query() high_value = df.query(“precio > 100 y cantidad < 50")

Esto resulta útil, especialmente cuando sus condiciones comienzan a acumularse o cuando desea que su código se vea lo suficientemente limpio como para poder volver a visitarlo una semana después sin preguntarse qué estaba pensando.

Es una actualización simple que hace que su código parezca más intencional y más fácil de mantener.

6. Convertir cadenas repetitivas en categóricas

Si tiene una columna llena de valores de texto repetidos, como categorías de productos o nombres de ubicaciones, convertirla a tipo categórico puede brindarle un aumento inmediato del rendimiento.

Lo he experimentado de primera mano.

Pandas almacena datos categóricos de una manera mucho más compacta reemplazando cada valor único con un código numérico interno.

Esto ayuda a reducir el uso de memoria y acelera las operaciones en esa columna.

# Convertir una columna de cadena a un tipo categórico df[“category”] = gl[“category”].astype(“categoría”)

Las categorías categóricas no ayudarán mucho con el texto desordenado y de formato libre, pero para las etiquetas estructuradas que se repiten en muchas filas, son una de las optimizaciones más simples y efectivas que puede realizar.

7. Cargue archivos grandes en fragmentos en lugar de todos a la vez

Una de las formas más rápidas de sobrecargar su sistema es intentar cargar un archivo CSV masivo de una vez.

Pandas intentará guardar todo en la memoria, y eso puede ralentizar las cosas o bloquear la sesión por completo.

La solución es cargar el archivo en partes manejables y procesar cada una a medida que llega. Este enfoque mantiene estable el uso de la memoria y aún le permite trabajar con todo el conjunto de datos.

# Procesar un archivo CSV grande en trozos trozos = []
para fragmento en pd.read_csv (“large_data.csv”, tamaño de fragmento = 100_000): fragmento[“total”] = trozo[“price”] * trozo[“quantity”]
trozos.append(fragmento) df = pd.concat(fragmentos, ignore_index=True)

La fragmentación es especialmente útil cuando se trata de registros, registros de transacciones o exportaciones sin procesar que son mucho más grandes de lo que una computadora portátil normal puede manejar cómodamente.

Aprendí esto de la manera más difícil cuando una vez intenté cargar un CSV de varios gigabytes de una sola vez y todo mi sistema respondió como si necesitara un momento para pensar en sus opciones de vida.

Después de esa experiencia, la fragmentación se convirtió en mi enfoque preferido.

En lugar de intentar cargar todo a la vez, tomas una pieza manejable, la procesas, guardas el resultado y luego pasas a la siguiente pieza.

El paso final de concat le brinda un conjunto de datos limpio y completamente procesado sin ejercer presión innecesaria sobre su máquina.

Parece demasiado simple, pero una vez que veas lo fluido que se vuelve el flujo de trabajo, te preguntarás por qué no empezaste a usarlo mucho antes.

Pensamientos finales

Trabajar con Pandas se vuelve mucho más fácil una vez que comienzas a utilizar las funciones diseñadas para hacer que tu flujo de trabajo sea más rápido y eficiente.

Las técnicas de este artículo no son complicadas, pero marcan una diferencia notable cuando las aplicas de manera constante.

Estas mejoras pueden parecer pequeñas individualmente, pero juntas pueden transformar la rapidez con la que se pasa de datos sin procesar a información significativa.

Si desarrolla buenos hábitos sobre cómo escribe y estructura su código Pandas, el rendimiento se convierte en un problema mucho menor.

Las pequeñas optimizaciones se suman y, con el tiempo, hacen que todo su flujo de trabajo se sienta más fluido y deliberado.