apply() mit GroupBy
Übergeben Sie groupby().apply() eine Funktion, die mehrere Zeilen verarbeitet, um komplexe Gruppenübersichten zu berechnen, die sich mit agg() nicht ausdrücken lassen.
apply() mit GroupBy ist eine kostenlose Pandas & NumPy Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Pandas & NumPy Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Pandas & NumPy Academy-Kurs umfasst insgesamt 4 Lektionen.
Warum GroupBy apply() benötigt
Die integrierte Methode agg() verarbeitet einfache Aggregationen wie Summe, Mittelwert und Anzahl — eine skalare Ausgabe pro Gruppe. Für manche Berechnungen auf Gruppenebene muss jedoch der gesamte Teil-DataFrame der Gruppe betrachtet werden, nicht nur eine einzelne Spalte. groupby().apply(func) übergibt Ihrer Funktion den vollständigen DataFrame der Gruppe und sammelt die Ergebnisse. Dadurch werden komplexe Zusammenfassungen möglich, die sich mit agg() nicht ausdrücken lassen.
import pandas as pd
import numpy as np
df = pd.DataFrame({
'region': ['North', 'North', 'South', 'South', 'North'],
'product': ['A', 'B', 'A', 'A', 'C'],
'revenue': [100, 250, 180, 90, 300]
})
print(df)Pro Gruppe einen Skalar zurückgeben
Wenn die an groupby().apply() übergebene Funktion einen Skalar zurückgibt, ist das Ergebnis eine Series, die nach den Gruppenschlüsseln indiziert ist — genau wie bei agg(). Diese Form ist nützlich, wenn der Skalar eine Logik über mehrere Spalten erfordert, beispielsweise das Verhältnis des Umsatzes des umsatzstärksten Produkts zum Gesamtumsatz der Gruppe. Dies lässt sich nicht in einer einzelnen agg()-Spaltenspezifikation ausdrücken.
def top_product_share(group):
top = group['revenue'].max()
total = group['revenue'].sum()
return top / total
share = df.groupby('region').apply(top_product_share)
print(share)Pro Gruppe eine Series zurückgeben
Wenn die Funktion eine pd.Series zurückgibt, besitzt das Ergebnis einen MultiIndex: Die äußere Ebene ist der Gruppenschlüssel, die innere Ebene der Index der Series. Dies ist nützlich, um mit einem einzigen apply-Aufruf mehrere Statistiken pro Gruppe zu berechnen und eine Übersichtstabelle zu erzeugen, in der jede Gruppe mehrere Zeilen mit Kennzahlen besitzt.
def group_stats(group):
return pd.Series({
'total': group['revenue'].sum(),
'top_product': group.loc[group['revenue'].idxmax(), 'product'],
'n_products': group['product'].nunique()
})
result = df.groupby('region').apply(group_stats)
print(result)Pro Gruppe einen DataFrame zurückgeben
Wenn die Funktion einen pd.DataFrame zurückgibt, fügt groupby().apply() alle Teil-DataFrames vertikal zusammen. Dies ist die leistungsfähigste Form: Sie können die Zeilen innerhalb jeder Gruppe filtern oder transformieren und eine veränderte Teilmenge zurückgeben. Beispielsweise können Sie nur die zwei umsatzstärksten Produkte jeder Region behalten.
def top2_per_region(group):
return group.nlargest(2, 'revenue')
top2 = df.groupby('region').apply(top2_per_region)
print(top2.reset_index(drop=True))Z-Scores innerhalb von Gruppen berechnen
Eine häufige Anwendung von groupby().apply() ist die Standardisierung innerhalb von Gruppen. Anstatt den Umsatz relativ zu allen Bestellungen zu normalisieren, wodurch Regionen miteinander vermischt werden, berechnen Sie den Z-Score des Umsatzes innerhalb jeder Region. Ein Z-Score von 2 im Norden bedeutet „2 Standardabweichungen über dem Durchschnitt des Nordens“ — ein aussagekräftigerer Vergleichswert als 2 Standardabweichungen über dem globalen Durchschnitt.
def within_group_zscore(group):
mean = group['revenue'].mean()
std = group['revenue'].std()
group = group.copy()
group['revenue_z'] = (group['revenue'] - mean) / std
return group
df_z = df.groupby('region').apply(within_group_zscore).reset_index(drop=True)
print(df_z)Benutzerdefinierte Aggregation: winsorisierter Mittelwert
Der winsorisierte Mittelwert begrenzt extreme Werte vor der Mittelwertbildung und ist dadurch bei schiefen Verteilungen robuster als der einfache Mittelwert. Diese benutzerdefinierte Aggregation lässt sich mit den Standardfunktionen von agg() nicht ausdrücken, ist mit groupby().apply() jedoch einfach umzusetzen: Begrenzen Sie die Werte innerhalb jeder Gruppe auf das 5. und 95. Perzentil und berechnen Sie anschließend den Mittelwert der begrenzten Werte.
def winsorised_mean(group, lower_pct=0.05, upper_pct=0.95):
col = group['revenue']
lo = col.quantile(lower_pct)
hi = col.quantile(upper_pct)
clipped = col.clip(lo, hi)
return clipped.mean()
wins_mean = df.groupby('region').apply(winsorised_mean)
print('Winsorised mean by region:')
print(wins_mean)Benutzerdefiniertes gleitendes Fenster pro Gruppe
Auf den gesamten DataFrame angewendete gleitende Fenster ignorieren Gruppengrenzen. Wenn Sie für eine Zeitreihe, in der zwei Produkte abwechselnd vorkommen, einen gleitenden Mittelwert über drei Zeilen berechnen, überschreitet das Fenster fälschlicherweise die Produktgrenzen. Wenden Sie das gleitende Fenster innerhalb von groupby().apply() an, damit jede Berechnung innerhalb ihrer Gruppe bleibt — beispielsweise für den gleitenden Umsatzmittelwert über drei Monate pro Region.
def group_rolling_mean(group, window=3):
group = group.sort_values('order_date').copy()
group['rolling_revenue'] = group['revenue'].rolling(window, min_periods=1).mean()
return group
# df_ts has order_date column
# df_rolled = df_ts.groupby('region').apply(group_rolling_mean).reset_index(drop=True)
print('Rolling window per group applied inside apply()')Parameter include_groups (Pandas 2.2+)
In Pandas 2.2 und höher gibt groupby().apply() eine FutureWarning aus, wenn die GroupBy-Schlüssel im DataFrame enthalten sind, den die Funktion erhält. Übergeben Sie include_groups=False, um die GroupBy-Spalten aus dem an die Funktion übergebenen Teil-DataFrame auszuschließen. Dadurch vermeiden Sie sowohl die Warnung als auch unbeabsichtigte Operationen an den Schlüsselspalten innerhalb des Funktionskörpers.
def revenue_only(group):
# group does not include 'region' column when include_groups=False
return group['revenue'].sum()
# result = df.groupby('region').apply(revenue_only, include_groups=False)
print('include_groups=False avoids FutureWarning in Pandas 2.2+')Ergebnisse von apply() mit reset_index kombinieren
Wenn groupby().apply() pro Gruppe einen DataFrame zurückgibt, besitzt das Ergebnis einen MultiIndex, der den Gruppenschlüssel als äußere Ebene enthält. Verwenden Sie reset_index(drop=True), um den Index wieder in einen einfachen ganzzahligen Bereich umzuwandeln. Alternativ können Sie reset_index(level=0) verwenden, um den Gruppenschlüssel in eine Spalte zu übernehmen und ihn in der Ausgabe explizit sichtbar zu machen.
result = df.groupby('region').apply(top2_per_region)
print('With MultiIndex:')
print(result.head())
print('\nAfter reset_index:')
print(result.reset_index(drop=True))Wann transform() gegenüber apply() vorzuziehen ist
groupby().apply() ist für komplexe Berechnungen auf Gruppenebene gedacht, deren Ergebnis eine andere Form als die Eingabe besitzt. groupby().transform() dient Berechnungen, die eine neue, am ursprünglichen Index ausgerichtete Spalte hinzufügen — beispielsweise dem Zurückschreiben des Gruppenmittelwerts in jede Zeile zur Normalisierung. Verwenden Sie transform, wenn das Ergebnis dieselbe Form wie der ursprüngliche DataFrame haben soll, und apply, wenn sich die Form des Ergebnisses unterscheidet.
# transform: adds group mean back to each row
df['group_mean_revenue'] = df.groupby('region')['revenue'].transform('mean')
# apply: computes one scalar per group
group_totals = df.groupby('region')['revenue'].apply(sum)
print(df[['region', 'revenue', 'group_mean_revenue']])Performance-Tipp: apply() bei einfachen Aggregationen vermeiden
groupby().apply() ist bei einfachen Operationen deutlich langsamer als groupby().agg(), da apply() für jede Gruppe ein vollständiges Python-Objekt erstellt. Verwenden Sie für Summen, Mittelwerte und Anzahlen immer agg(). Setzen Sie apply() nur dort ein, wo der vollständige Gruppen-DataFrame tatsächlich benötigt wird — etwa bei bedingter Logik über mehrere Spalten, benutzerdefinierten Statistiken oder beim Filtern innerhalb von Gruppen.
# SLOW: apply for simple sum
slow = df.groupby('region').apply(lambda g: g['revenue'].sum())
# FAST: native agg
fast = df.groupby('region')['revenue'].sum()
print('Both produce the same result:')
print(fast.equals(slow))Kurze Überprüfung
Testen Sie Ihr Verständnis der Konzepte zur Datenanalyse aus dieser Lektion.
Zusammenfassung der Lektion
In dieser Lektion haben Sie Folgendes gelernt: Skalare, Series und DataFrames mit groupby().apply() zurückzugeben, Z-Scores innerhalb von Gruppen und benutzerdefinierte robuste Statistiken zu berechnen und zwischen apply(), agg() und transform() für Operationen auf Gruppenebene zu wählen. Als Nächstes sehen wir uns map() und applymap() für elementweise Operationen auf Series und DataFrames an.
Häufig gestellte Fragen
Ist die Lektion „apply() mit GroupBy“ kostenlos?
Ja — der vollständige Text von „apply() mit GroupBy“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Pandas & NumPy Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Pandas & NumPy Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „apply() mit GroupBy“?
Übergeben Sie groupby().apply() eine Funktion, die mehrere Zeilen verarbeitet, um komplexe Gruppenübersichten zu berechnen, die sich mit agg() nicht ausdrücken lassen. Du übst Pandas & NumPy Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Pandas & NumPy Academy zu starten?
Keine Vorkenntnisse erforderlich. Pandas & NumPy Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „apply() mit GroupBy“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Pandas & NumPy Academy-Lektion Code schreiben und ausführen?
Ja. Jede Pandas & NumPy Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- apply() auf Spalten und Zeilen
- apply() mit GroupBy
- map() und applymap() für elementweise Operationen
- Method Chaining mit pipe()