Agrégation groupée chez les pandas



L'agrégation est l'une des opérations les plus courantes dans l'analyse des données. Différentes technologies nous offrent un tas de façons de regrouper et d'agréger efficacement les domaines qui nous intéressent (colonnes, attributs). Cet article parlera de la mise en œuvre de l'agrégation dans les pandas.
Dans ma spécialisation, je travaille très peu avec python, mais j'entends souvent parler des avantages et de la puissance de ce langage, surtout quand il s'agit de travailler avec des données. Par conséquent, je vais dessiner ici une opération parallèle avec T-SQL et donner quelques exemples de code. Comme données, j'utiliserai probablement l'ensemble de données le plus populaire - Irises Fisher .

La première chose qui vient à l'esprit est d'obtenir la valeur maximale, minimale ou moyenne pour l'un des paramètres de l'iris et de les regrouper par espèce de cette plante, qui en python utilisant des pandas ressemblera à ceci:

import pandas as pd

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

Résultat:

| variété | sepal.length |
|: ----------- | ---------------: |
| Setosa | 5.8 |
| Versicolor | 7 |
| Virginica | 7,9 |

Ou alors:

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

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

Résultat:

| variété | maxSepalLength | minSepalLength |
|: ----------- | -----------------: | ----------------- : |
| Setosa | 5.8 | 4.3 |
| Versicolor | 7 | 4.9 |
| Virginica | 7,9 | 4.9 |

Ou en utilisant des expressions 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())

Résultat:

| variété | <lambda_0> | <lambda_1> |
|: ----------- | -------------: | -------------: |
| Setosa | 5.8 | 4.3 |
| Versicolor | 7 | 4.9 |
| Virginica | 7,9 | 4.9 |

Fonction d'instance DataFrame
to_markdown()
vous permet d'afficher une table (DataFrame) sous la forme habituelle (console).

Sur T-SQL, cette opération ressemble à ceci:

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

Résultat:

Setosa 5.8
Versicolor 7.0
Virginica 7.9

Mais supposons maintenant que nous voulons obtenir les valeurs maximale et minimale (si vous aimez la moyenne) pour tous les paramètres de l'iris, naturellement pour chaque type de plante, le code T-SQL a été généré ici:

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

Résultat:

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

Dans les pandas, la possibilité d'agrégation de groupe n'apparaissait que dans la version 0.25.0 du 18 juillet 2019 (ce qui était fait avant) ?) et il existe plusieurs variantes, considérez-les:

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'),
    )

Résultat:

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

Fonction
DataFrame.agg(self, func, axis=0, *args, **kwargs)

permet l'agrégation de plusieurs opérations sur un axe donné. En tant que paramètres, la fonction reçoit ** kwargs (arguments nommés, voir l'article sur habr pour plus de détails ), qui sont une colonne sur laquelle l'opération est effectuée et le nom de la fonction d'agrégation entre guillemets simples. L'enregistrement semble assez volumineux. Passez.

La même solution utilisant des expressions lambda semble beaucoup plus concise et simple:

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

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

Résultat:

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

J'entends souvent parler beaucoup moins d'écrit lorsque Python lors de la résolution du même type de problème par rapport à d'autres langues. Ici, en comparaison avec T-SQL, on peut être d'accord avec cela, mais la clarté et la séquence des expressions d'outils linguistiques tels que SQL ou T-SQL est complètement perdue (opinion personnelle).

Ensemble et code de données de l'article peuvent être trouvés ici

Quoi de neuf en 0.25.0 (18 Juillet 2019)

pandas géants

All Articles