Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

?id=232bb6df-7d2c-4828-9da3-d0aabe509d1d

pandas 2.0 para ciencia de datos: todas sus novedades

Imagen ornamental, 2 osos panda con el logo de pandas encima. Fotografía de base por Pascal Müller en Unsplash, CC0

¿Que és pandas?

Pandas es una biblioteca de código abierto escrita en Python que proporciona estructuras de datos de alto rendimiento y fáciles de utilizar, así como herramientas de análisis de datos. Se suele utilizar para manipulación y análisis de datos. Utiliza(ba) NumPy por debajo (ahora verás el porqué de ese "(ba)").

Pandas proporciona herramientas para leer y escribir datos en diferentes formatos (como CSV, Excel o SQL), y ofrece una amplia gama de funciones para el análisis de datos, como la agregación, la agrupación, la fusión o la transformación de datos. Con pandas, los usuarios pueden realizar tareas como la limpieza, la manipulación y transformación, la agregación y la visualización de datos de manera eficiente y sencilla.

Pandas proporciona dos estructuras de datos principales: Series y DataFrame:

  • Un Series es un objeto similar a un array de una sola dimensión que puede contener cualquier tipo de datos, como números, cadenas o booleanos.
  • Un DataFrame es una estructura de datos tabular bidimensional que puede contener varias columnas de diferentes tipos de datos: números, cadenas, booleanos... o incluso otros objetos Series o DataFrames.

Pandas es, hoy por hoy, una biblioteca esencial para cualquier persona que trabaje con datos en Python.

pandas 2.0

Pandas 2.0 por fin está aquí. Se trata de una versión que lleva mucho tiempo en desarrollo y que era muy esperada por la comunidad.

Esta versión viene con nuevas funciones, correcciones de errores y, sobre todo, con cambios internos muy importantes para ofrecer un rendimiento muy mejorado (pero tienes que leer las salvedades más abajo).

IMPORTANTE: Se recomienda que actualices tu código a pandas 1.5.3 antes de dar el salto directo a pandas 2.0. De este modo, te aseguras de que va a funcionar, pero al mismo tiempo te generará mensajes de advertencia sobre funciones descatalogadas (deprecated) o problemas que te puede dar la versión 2.0. Ten en cuenta que hay más de 150 características "deprecadas" en esta versión que se han ido anunciando en las sucesivas 1.x en los últimos años.

Vamos a ver las novedades más importantes de esta versión...

¿Adiós NumPy, hola Apache Arrow?

La actualización principal de esta versión tiene que ver con el uso de Apache Arrow (PyArrow) en lugar de NumPy como "backend" para pandas. Este cambio puede parecer poco más que una curiosidad interna, sobre todo porque se ha tenido mucho cuidado con romper la compatibilidad lo menos posible, pero sus implicaciones son muy importantes.

Apache Arrow está orientado hacia el rendimiento y la eficiencia en el manejo de datos en memoria, tanto tabulares como jerárquicos, además de sacar el máximo partido a las modernas GPUs.

MUY IMPORTANTE: aunque verás en todas partes reseñado que ahora Apache Arrow ha sustituido a NumPy, no es cierto. NumPy sigue estando ahí y sigue siendo el "backend" por defecto. Existe un nuevo "backend" basado en Arrow (pyarrow) que puedes utilizar y que es del que te estoy hablando en este apartado, pero no soporta aún todas las operaciones del anterior y por eso no es todavía el que se utiliza por defecto. Aun así, es por donde va el futuro y, por lo tanto, deberías prestarle mucha atención.

Solo por el cambio de NumPy a Apache Arrow tenemos multitud de ventajas, entre las que cabe destacar (fuente: Marc García, Datapythonista - pandas 2.0 and the Arrow revolution (part I)):

  • Velocidad: como decíamos antes, Arrow está centrado en el rendimiento y supera por mucho a NumPy, especialmente con algunos tipos de datos, como por ejemplo las cadenas de caracteres:
Operación NumPy Arrow Ganancia de velocidad
read parquet (50Mb) 141 ms 87 ms 1.6x
mean (int64) 2.03 ms 1.11 ms 1.8x
mean (float64) 3.56 ms 1.73 ms 2.1x
endswith (string) 471 ms 14.9 ms 31.6x
  • Tipos de datos: a pesar de que NumPy proporciona un gran soporte para valores enteros, flotantes, booleanos y fecha y hora, se queda corto para otros tipos de datos. Arrow tiene un mejor soporte para fechas y horas, utiliza un solo bit para tipos booleanos (en lugar de los 8 bits de NumPy, usando 8 veces menos memoria), y tiene soporte nativo para otros tipos como campos de tipo bit, valores decimales y otros tipos complejos.
  • Categorías: Arrow presenta otra gran ventaja para una operación muy común: las categorías o etiquetas. Arrow tiene un tipo específico para ello que, en lugar de almacenar cadenas de texto para cada elemento categorizado que tengamos, internamente usa un índice numérico para cada posible valor, con las cadenas relacionadas guardadas en otra parte y solo una vez. Esto parece algo evidente, pero no se podía hacer con NumPy. Gracias a ello se puede ahorrar muchísima memoria en conjuntos de datos grandes categorizados o con muchas cadenas que se repiten, algo con lo que es muy habitual encontrarse.
  • Valores perdidos: representar de forma eficiente los valores que faltan en los datos de partida para el análisis puede ser muy complicado, y es un problema muy frecuente. En Python se puede utilizar None como comodín para indicar que un objeto falta. Sin embargo, en las representaciones internas de datos hay que tratar de aprovechar todos los bits de memoria y, en muchas ocasiones, la única opción es forzar la conversión de datos numéricos (incluso enteros) a coma flotante para usar NaN, un valor especial que se puede almacenar en memoria junto al resto de números. Para evitar estas conversiones, recientemente pandas comenzó a permitir el uso de una matriz auxiliar para almacenar las posiciones de los valores perdidos. Este problema viene solucionado de serie con Arrow, que ya incluye en sus representaciones internas formas de indicar valores perdidos, por lo que no son necesarias conversiones ni matrices adicionales.
  • Interoperabilidad: en este ámbito los beneficios de Arrow vienen por duplicado. En primer lugar, porque es más fácil y más estándar compartir datos entre diferentes programas con esta biblioteca. Y en segundo, porque permite compartir datos directamente en memoria, de modo que dos programas que necesiten los mismos datos no tienen que duplicarlos, sino que usan los mismos 😲. Vale, esto no es muy habitual, pero cuando lo necesites, la diferencia de rendimiento será abismal.

Y todo ello, además, procurando que se rompa la compatibilidad hacia atrás lo menos posible, de forma que impacte poco en nuestros desarrollos y sea relativamente fácil migrar a la versión 2.0.

En el artículo de Marc García referenciado al principio de este epígrafe, del equipo "core" de pandas, puedes encontrar un montón de ejemplos y código sobre todo esto.

Logotipo de PyArrow

Índices con tipos arbitrarios dtype

En versiones anteriores, un índice solo admitía los tipos dtype de NumPy: int64, float64 y uint64. Esto generaba los tipos Index específicos: Int64Index, Float64Index o UInt64Index. Estas clases ahora han desaparecido (se habían declarado como obsoletas en pandas 1.4), y todos los índices numéricos se representan como la clase única Index, pero con un dtype asociado, por ejemplo:

In [1]: pd.Index([1, 2, 3], dtype="int64")
Out[1]: Index([1, 2, 3], dtype='int64')
In [2]: pd.Index([1, 2, 3], dtype="int32")
Out[2]: Index([1, 2, 3], dtype='int32')

Esto tiene la ventaja adicional de que muchas operaciones que antes implicaban la creación de índices de 64 bit ahora pueden crear índices de orden inferior, por ejemplo de 32 bits (consumiendo la mitad de memoria), consiguiendo mayor eficiencia y rendimiento.

Cambio de comportamiento en numeric_only para funciones de agregación

En versiones anteriores, podíamos llamar a funciones de agregación en un DataFrame con tipos heterogéneos (varios tipos mezclados en los datos) y obtener diferentes resultados de esta operación. Por ejemplo, a veces esa agregación funcionaba y simplemente dejaba fuera a los dtype no numéricos. En otras ocasiones simplemente se generaba un error y punto.

El argumento numeric_only ahora es consistente y funcionará al aplicarse en un DataFrame con tipos de datos no numéricos. Para obtener el mismo comportamiento que antes puedes establecer numeric_only a True o hacer que tu DataFrame solo contenga columnas numéricas y así evitarás eliminar por error columnas relevantes de dicho DataFrame al hacer la agregación.

Esto es lo que pasaba en versiones anteriores al calcular la media de los valores de un DataFrame que no tenía solo números:

In[2] df = DataFrame({"a": [1, 2, 3], "b": ["x", "y", "z"]})
In[3] df.mean()
Out[3]: 
a    2.0
dtype: float64

Como ves, en este caso funcionaba, pero no utilizaba los valores no numéricos que había. En pandas 2.0 esta operación ahora genera un error para evitar descartar columnas relevantes en estas agregaciones:

TypeError: Could not convert ['xyz'] to numeric

Otras mejoras

  • Mejor soporte para dtypes anulables y matrices de extensión: internamente, muchas operaciones ahora usan semántica anulable en lugar de conversión a objeto (boxing) cuando se usan dtypes anulables como Int64, boolean o Float64. El manejo interno de los arrays de extensión ha ido mejorando constantemente ya en las versiones 1.x hasta llegar a los actuales de la 2.0. Estas mejoras se traducen un montón de ganancias de rendimiento.
  • DataFrames respaldados por Pyarrow: ya en la versión 1.5.0 se incluyó una nueva matriz de extensión que permitía a los usuarios crear DataFrames respaldados por matrices PyArrow. Estas matrices de extensión proporcionan una gran mejora al operar en columnas con cadenas de texto, ya que la representación de objetos NumPy para esto no es muy eficiente, como se comentó antes. La API que salió con 1.5.0 era bastante experimental y seguía usando NumPy para casi todo. Con pandas 2.0 y PyArrow 7.0 ahora es posible utilizar en muchos más métodos las funciones de cálculo de PyArrow correspondientes, mejorando significativamente el rendimiento y eliminando muchas advertencias de rendimiento.
  • Resolución de no nanosegundos en marcas de tiempo: un problema en versiones anteriores era que las marcas de tiempo (TimeStamps) siempre se representaban con una resolución de nanosegundos. Como consecuencia, no había forma de representar fechas anteriores al 1 de enero de 1970 o posteriores al 11 de abril de 2264. Esto traía problemas en ciertas comunidades de investigadores que analizan datos de series temporales que abarcan periodos mucho mayores. La versión 2.0 introduce compatibilidad con otras resoluciones, y añade soporte para resolución de segundos, milisegundos y microsegundos. Esto permite rangos de tiempo de hasta +/- 2.9e11 años y, por lo tanto, debería cubrir los casos de uso más habituales.
  • Mejoras en Copy-on-Write (CoW): cualquier DataFrame o Serie derivada de otra en cualquier modo siempre se comporta como una copia. Debido a ello, sólo se pueden cambiar los valores de un objeto modificando el objeto en sí, no sobre una copia. CoW no permite actualizar un DataFrame o una Serie que comparte datos con otro objeto DataFrame o Serie. En pandas 2.0 casi todos los métodos utilizan un mecanismo de copia diferida para retrasar el copiado de los datos subyacentes el mayor tiempo posible. Sin CoW habilitado, la mayoría de los métodos realizan copias defensivas para evitar efectos secundarios cuando un objeto se modifica más adelante. Esto da como resultado un alto uso de memoria y un tiempo de ejecución relativamente alto. Copy-on-Write permite eliminar todas esas copias defensivas y diferir las copias reales hasta que se modifiquen de verdad los datos de un objeto. El resultado es un mejor rendimiento en general. Más información en: Copy-on-Write (CoW) en la documentación oficial de pandas.
  • Mejoras en el manejo de fechas y horas: ahora no solo son mucho mas eficientes y rápidas (hasta 10 veces más rápidas) sino que el manejo de datos de tipo DateTime en pandas es mucho más consistente.

En las notas de la versión puedes encontrar muchos más detalles de todo esto.

Fecha de publicación:
campusMVP campusMVP es la mejor forma de aprender a programar online y en español. En nuestros cursos solamente encontrarás contenidos propios de alta calidad (teoría+vídeos+prácticas) creados y tutelados por los principales expertos del sector. Nosotros vamos mucho más allá de una simple colección de vídeos colgados en Internet porque nuestro principal objetivo es que tú aprendas. Ver todos los posts de campusMVP

Boletín campusMVP.es

Solo cosas útiles. Una vez al mes.

🚀 Únete a miles de desarrolladores

DATE DE ALTA

x No me interesa | x Ya soy suscriptor

La mejor formación online para desarrolladores como tú

Agregar comentario

Los datos anteriores se utilizarán exclusivamente para permitirte hacer el comentario y, si lo seleccionas, notificarte de nuevos comentarios en este artículo, pero no se procesarán ni se utilizarán para ningún otro propósito. Lee nuestra política de privacidad.