Groupby-Aggregation in Pandas



Die Aggregation ist eine der häufigsten Operationen bei der Datenanalyse. Verschiedene Technologien bieten uns eine Reihe von Möglichkeiten, die für uns interessanten Bereiche (Spalten, Attribute) effektiv zu gruppieren und zu aggregieren. Dieser Artikel befasst sich mit der Implementierung der Aggregation in Pandas.
In meiner Spezialisierung arbeite ich sehr wenig mit Python, aber ich höre oft über die Vorteile und die Leistungsfähigkeit dieser Sprache, insbesondere wenn es um die Arbeit mit Daten geht. Daher werde ich hier eine Paralleloperation mit T-SQL zeichnen und einige Codebeispiele geben. Als Daten werde ich wahrscheinlich den beliebtesten Datensatz verwenden - Irises Fisher .

Das erste, was mir in den Sinn kommt, ist, den Maximal-, Minimal- oder Durchschnittswert für einen der Irisparameter und die Gruppe nach Arten dieser Pflanze zu ermitteln, die in Python mit Pandas ungefähr so ​​aussehen:

import pandas as pd

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

Ergebnis:

| Vielfalt | sepal.length |
|: ----------- | ---------------: |
| Setosa | 5.8 |
| Versicolor | 7 |
| Virginica | 7.9 |

Oder so:

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

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

Ergebnis:

| Vielfalt | maxSepalLength | minSepalLength |
|: ----------- | -----------------: | ----------------- : |
| Setosa | 5.8 | 4.3 |
| Versicolor | 7 | 4.9 |
| Virginica | 7.9 | 4.9 |

Oder mit Lambda-Ausdrücken:

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())

Ergebnis:

| Vielfalt | <lambda_0> | <lambda_1> |
|: ----------- | -------------: | -------------: |
| Setosa | 5.8 | 4.3 |
| Versicolor | 7 | 4.9 |
| Virginica | 7.9 | 4.9 |

DataFrame-Instanzfunktion
to_markdown()
Mit dieser Option können Sie eine Tabelle (DataFrame) in der üblichen Form (Konsole) anzeigen.

Unter T-SQL sieht diese Operation ungefähr so ​​aus:

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

Ergebnis:

Setosa 5.8
Versicolor 7.0
Virginica 7.9

Angenommen, wir möchten jetzt sowohl die Maximal- als auch die Minimalwerte (wenn Sie den Durchschnitt mögen) für alle Parameter der Iris erhalten, natürlich für jeden Anlagentyp. Hier wurde der T-SQL-Code generiert:

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

Ergebnis:

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

Bei Pandas trat die Möglichkeit der Gruppenaggregation nur in Version 0.25.0 vom 18. Juli 2019 auf (was zuvor getan wurde) ?) und es gibt verschiedene Variationen, betrachten Sie sie:

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

Ergebnis:

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

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

Ermöglicht die Aggregation mehrerer Operationen auf einer bestimmten Achse. Als Parameter erhält die Funktion ** kwargs (benannte Argumente, Einzelheiten finden Sie im Artikel über habr ), eine Spalte, für die die Operation ausgeführt wird, und den Namen der Aggregationsfunktion in einfachen Anführungszeichen. Die Aufnahme sieht ziemlich voluminös aus. Mach weiter.

Die gleiche Lösung mit Lambda-Ausdrücken sieht viel prägnanter und einfacher aus:

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

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

Ergebnis:

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

Ich höre oft viel weniger geschrieben, wenn Python die gleiche Art von Problem im Vergleich zu anderen Sprachen löst. Hier kann man im Vergleich zu T-SQL dem zustimmen, aber die Klarheit und Reihenfolge der Ausdrücke von Sprachwerkzeugen wie SQL oder T-SQL geht völlig verloren (persönliche Meinung).

Den Datensatz und den Code aus dem Artikel finden Sie hier.

Was ist neu in Pandas von 0.25.0 (18. Juli 2019)

?

All Articles