Agrupación grupal en pandas



La agregación es una de las operaciones más comunes en el análisis de datos. Las diferentes tecnologías nos ofrecen muchas formas de agrupar y agregar de manera efectiva los campos que nos interesan (columnas, atributos). Este artículo hablará sobre la implementación de la agregación en pandas.
En mi especialización, trabajo muy poco con Python, pero a menudo escucho sobre los pros y el poder de este lenguaje, especialmente cuando se trata de trabajar con datos. Por lo tanto, dibujaré aquí una operación paralela con T-SQL y daré algunos ejemplos de código. Como datos usaré probablemente el conjunto de datos más popular: Irises Fisher .

Lo primero que viene a la mente es obtener el valor máximo, mínimo o promedio para cualquiera de los parámetros del iris y agruparlos por especie de esta planta, que en python usando pandas se verá así:

import pandas as pd

df = pd.read_csv('iris.csv', delimiter = ',')
print(df.groupby('variety').max()[['sepalLength']].to_markdown())

Resultado:

| variedad | longitud de separación |
|: ----------- | ---------------: |
El | Setosa | 5,8 |
El | Versicolor | 7 |
El | Virginica | 7,9 |

Más o menos:

import pandas as pd
df = pd.read_csv('iris.csv', delimiter = ',')

print(df.groupby('variety').sepalLength.agg(
    maxSepalLength  = 'max',
    minSepalLength  = 'min',
    ).to_markdown())

Resultado:

| variedad | maxSepalLength | minSepalLength |
|: ----------- | -----------------: | ----------------- : |
El | Setosa | 5,8 | 4.3 |
El | Versicolor | 7 | 4.9 |
El | Virginica | 7,9 | 4.9 |

O usando expresiones lambda:

import pandas as pd
df = pd.read_csv('iris.csv', delimiter = ',')

print(df.groupby('variety').sepalLength.agg([
    lambda x: x.max(), 
    lambda x: x.min()
    ]).to_markdown())

Resultado:

| variedad | <lambda_0> | <lambda_1> |
|: ----------- | -------------: | -------------: |
El | Setosa | 5,8 | 4.3 |
El | Versicolor | 7 | 4.9 |
El | Virginica | 7,9 | 4.9 |

Función de instancia de marco de datos
to_markdown()
le permite mostrar una tabla (DataFrame) en el formulario habitual (consola).

En T-SQL, esta operación se ve así:

select i.Variety, max(i.SepalLength) as maxSepalLength
    from Iris i
        group by i.Variety

Resultado:

Setosa 5.8
Versicolor 7.0
Virginica 7.9

Pero supongamos que ahora queremos obtener los valores máximos y mínimos (si le gusta el promedio) para todos los parámetros del iris, naturalmente para cada tipo de planta, el código T-SQL se ha generado aquí:

select
	i.Variety 
	,max(i.SepalLength) as maxSepalLength 
	,min(i.SepalLength) as minSepalLength
	,max(i.SepalWidth) as maxSepalWidth
	,min(i.SepalWidth) as minSepalWidth
	,max(i.PetalLength) as maxPetalLength
	,min(i.PetalLength) as mibPetalLength
	,max(i.PetalWidth) as maxPetalWidth
	,min(i.PetalWidth) as minPetalWidth
from Iris i
	group by i.Variety

Resultado:

Setosa 5.8 4.3 4.4 2.3 1.9 1.0 0.6 0.1
Versicolor 7.0 4.9 3.4 2.0 5.1 3.0 1.8 1.0
Virginica 7.9 4.9 3.8 2.2 6.9 4.5 2.5 1.4

En pandas, la posibilidad de agregación grupal apareció solo en la versión 0.25.0 del 18 de julio de 2019 (lo que se hizo antes) ?) y hay varias variaciones, considérelas:

import pandas as pd
df = pd.read_csv('iris.csv', delimiter = ',')

df.groupby('variety').agg(
    maxSepalLength = pd.NamedAgg(column = 'sepalLength', aggfunc = 'max'),
    minSepalLength = pd.NamedAgg(column = 'sepalLength', aggfunc = 'min'),
    maxSepalWidth = pd.NamedAgg(column = 'sepalWidth', aggfunc = 'max'),
    minSepalWidth = pd.NamedAgg(column = 'sepalWidth', aggfunc = 'min'),
    maxPetalLength = pd.NamedAgg(column = 'petalLength', aggfunc = 'max'),
    minPetalLength = pd.NamedAgg(column = 'petalLength', aggfunc = 'min'),
    maxPetalWidth = pd.NamedAgg(column = 'petalWidth', aggfunc = 'max'),
    minPetalWidth = pd.NamedAgg(column = 'petalWidth', aggfunc = 'min'),
    )

Resultado:

Setosa 5.8 4.3 4.4 2.3 1.9 1.0 0.6 0.1
Versicolor 7.0 4.9 3.4 2.0 5.1 3.0 1.8 1.0
Virginica 7.9 4.9 3.8 2.2 6.9 4.5 2.5 1.4

Función
DataFrame.agg(self, func, axis=0, *args, **kwargs)

permite la agregación de varias operaciones en un eje dado. Como parámetros, la función recibe ** kwargs (argumentos con nombre, consulte el artículo sobre habr para más detalles ), que son una columna en la que se realiza la operación y el nombre de la función de agregación entre comillas simples. La grabación se ve bastante voluminosa. Siga adelante.

La misma solución que usa expresiones lambda parece mucho más concisa y simple:

import pandas as pd
df = pd.read_csv('iris.csv', delimiter = ',')

df.groupby('variety').agg([
    lambda x: x.max(),
    lambda x: x.min()
    ])

Resultado:

Setosa 5.8 4.3 4.4 2.3 1.9 1.0 0.6 0.1
Versicolor 7.0 4.9 3.4 2.0 5.1 3.0 1.8 1.0
Virginica 7.9 4.9 3.8 2.2 6.9 4.5 2.5 1.4

A menudo escucho mucho menos escrito cuando Python al resolver el mismo tipo de problema en comparación con otros idiomas. Aquí, en comparación con T-SQL, uno puede estar de acuerdo con esto, pero la claridad y la secuencia de expresiones de herramientas lingüísticas como SQL o T-SQL se pierde por completo (opinión personal).

Conjunto de datos y el código del artículo se pueden encontrar aquí

¿Qué hay de nuevo en 0.25.0 (18 de julio de 2019)

pandas

All Articles