

Bild vom Autor
# Einführung
Während groupby().sum() Und groupby().imply() eignen sich intestine für schnelle Überprüfungen, Metriken auf Produktionsebene erfordern robustere Lösungen. Tabellen aus der realen Welt umfassen oft mehrere Schlüssel, Zeitreihendaten, Gewichtungen und verschiedene Bedingungen wie Werbeaktionen, Retouren oder Ausreißer.
Das bedeutet, dass Sie häufig Summen und Raten berechnen, Elemente innerhalb jedes Segments einordnen, Daten nach Kalenderbereichen zusammenfassen und dann Gruppenstatistiken zur Modellierung wieder mit den ursprünglichen Zeilen zusammenführen müssen. Dieser Artikel führt Sie durch fortgeschrittene Gruppierungstechniken mit Pandas Bibliothek, um diese komplexen Szenarien effektiv zu bewältigen.
# Den richtigen Modus auswählen
// Verwenden von agg zum Reduzieren von Gruppen auf eine Zeile
Verwenden agg wenn Sie einen Datensatz professional Gruppe benötigen, z. B. Summen, Mittelwerte, Mediane, Min./Max.-Werte und benutzerdefinierte vektorisierte Reduzierungen.
out = (
df.groupby(('retailer', 'cat'), as_index=False, type=False)
.agg(gross sales=('rev', 'sum'),
orders=('order_id', 'nunique'),
avg_price=('value', 'imply'))
)
Dies ist intestine für KPI-Tabellen (Key Efficiency Indicator), wöchentliche Rollups und Zusammenfassungen mehrerer Metriken.
// Verwenden von „Remodel“, um Statistiken zurück an Zeilen zu übertragen
Der rework Die Methode gibt ein Ergebnis mit derselben Type wie die Eingabe zurück. Es ist superb zum Erstellen von Options, die Sie in jeder Zeile benötigen, wie z. B. Z-Scores, gruppeninterne Anteile oder gruppenweise Füllungen.
g = df.groupby('retailer')('rev')
df('rev_z') = (df('rev') - g.rework('imply')) / g.rework('std')
df('rev_share') = df('rev') / g.rework('sum')
Dies ist intestine für die Modellierung von Merkmalen, Qualitätssicherungsverhältnissen und Imputationen.
// Verwenden von „Anwenden“ für benutzerdefinierte Logik professional Gruppe
Verwenden apply nur wenn die erforderliche Logik nicht mit integrierten Funktionen ausgedrückt werden kann. Es ist langsamer und schwieriger zu optimieren, additionally sollten Sie es versuchen agg oder rework Erste.
def capped_mean(s):
q1, q3 = s.quantile((.25, .75))
return s.clip(q1, q3).imply()
df.groupby('retailer')('rev').apply(capped_mean)
Dies ist intestine für maßgeschneiderte Regeln und kleine Gruppen.
// Filter verwenden, um ganze Gruppen beizubehalten oder zu löschen
Der filter Mit dieser Methode können ganze Gruppen eine Bedingung bestehen oder nicht bestehen. Dies ist praktisch für Datenqualitätsregeln und Schwellenwerte.
large = df.groupby('retailer').filter(lambda g: g('order_id').nunique() >= 100)
Dies ist intestine für Kohorten mit minimaler Größe und zum Entfernen dünn besetzter Kategorien vor der Aggregation.
# Gruppierung mit mehreren Schlüsseln und benannte Aggregationen
// Gruppierung nach mehreren Schlüsseln
Sie können die Ausgabeform und -reihenfolge steuern, sodass die Ergebnisse direkt in ein Enterprise-Intelligence-Device übernommen werden können.
g = df.groupby(('retailer', 'cat'), as_index=False, type=False, noticed=True)
as_index=FalseGibt einen flachen DataFrame zurück, der einfacher zu verbinden und zu exportieren isttype=Falsevermeidet die Neuordnung von Gruppen, was Arbeit spart, wenn die Reihenfolge irrelevant istnoticed=True(mit kategorialen Spalten) löscht nicht verwendete Kategoriepaare
// Benannte Aggregationen verwenden
Benannte Aggregationen erzeugen lesbare, SQL-ähnliche Spaltennamen.
out = (
df.groupby(('retailer', 'cat'))
.agg(gross sales=('rev', 'sum'),
orders=('order_id', 'nunique'), # use your id column right here
avg_price=('value', 'imply'))
)
// Aufräumen von Spalten
Wenn Sie mehrere Aggregationen stapeln, erhalten Sie eine MultiIndex. Reduzieren Sie es einmal und standardisieren Sie die Spaltenreihenfolge.
out = out.reset_index()
out.columns = (
'_'.be a part of(c) if isinstance(c, tuple) else c
for c in out.columns
)
# elective: guarantee business-friendly column order
cols = ('retailer', 'cat', 'orders', 'gross sales', 'avg_price')
out = out(cols)
# Bedingte Aggregationen Ohne Anwendung
// Verwenden von Boolean-Masks Math Inside agg
Wenn eine Maske von anderen Spalten abhängt, richten Sie die Daten nach ihrem Index aus.
# promo gross sales and promo charge by (retailer, cat)
cond = df('is_promo')
out = df.groupby(('retailer', 'cat')).agg(
promo_sales=('rev', lambda s: s(cond.loc(s.index)).sum()),
promo_rate=('is_promo', 'imply') # proportion of promo rows
)
// Berechnen von Raten und Proportionen
Ein Tarif ist einfach sum(masks) / measurementwas dem Mittelwert einer booleschen Spalte entspricht.
df('is_return') = df('standing').eq('returned')
charges = df.groupby('retailer').agg(return_rate=('is_return', 'imply'))
// Erstellen von Fenstern im Kohortenstil
Berechnen Sie zunächst Masken mit Datumsgrenzen vor und aggregieren Sie dann die Daten.
# instance: repeat buy inside 30 days of first buy per buyer cohort
first_ts = df.groupby('customer_id')('ts').rework('min')
within_30 = (df('ts') <= first_ts + pd.Timedelta('30D')) & (df('ts') > first_ts)
# buyer cohort = month of first buy
df('cohort') = first_ts.dt.to_period('M').astype(str)
repeat_30_rate = (
df.groupby('cohort')
.agg(repeat_30_rate=('within_30', 'imply'))
.rename_axis(None)
)
# Gewichtete Metriken professional Gruppe
// Implementierung eines gewichteten Durchschnittsmusters
Vektorisieren Sie die Mathematik und schützen Sie sich vor Divisionen mit Nullgewicht.
import numpy as np
tmp = df.assign(wx=df('value') * df('qty'))
agg = tmp.groupby(('retailer', 'cat')).agg(wx=('wx', 'sum'), w=('qty', 'sum'))
# weighted common value per (retailer, cat)
agg('wavg_price') = np.the place(agg('w') > 0, agg('wx') / agg('w'), np.nan)
// Sicherer Umgang mit NaN-Werten
Entscheiden Sie, was für leere Gruppen oder alle zurückgegeben werden soll.NaN Werte. Zwei häufige Optionen sind:
# 1) Return NaN (clear, most secure for downstream stats)
agg('wavg_price') = np.the place(agg('w') > 0, agg('wx') / agg('w'), np.nan)
# 2) Fallback to unweighted imply if all weights are zero (specific coverage)
mean_price = df.groupby(('retailer', 'cat'))('value').imply()
agg('wavg_price_safe') = np.the place(
agg('w') > 0, agg('wx') / agg('w'), mean_price.reindex(agg.index).to_numpy()
)
# Zeitbewusste Gruppierung
// Verwenden von pd.Grouper mit einer Häufigkeit
Beachten Sie Kalendergrenzen für KPIs, indem Sie Zeitreihendaten in bestimmte Intervalle gruppieren.
weekly = df.groupby(('retailer', pd.Grouper(key='ts', freq='W')), noticed=True).agg(
gross sales=('rev', 'sum'), orders=('order_id', 'nunique')
)
// Anwenden rollierender/erweiternder Fenster professional Gruppe
Sortieren Sie Ihre Daten immer zuerst und richten Sie sie anhand der Zeitstempelspalte aus.
df = df.sort_values(('customer_id', 'ts'))
df('rev_30d_mean') = (
df.groupby('customer_id')
.rolling('30D', on='ts')('rev').imply()
.reset_index(degree=0, drop=True)
)
// Vermeidung von Datenlecks
Halten Sie die chronologische Reihenfolge ein und stellen Sie sicher, dass Home windows nur vergangene Daten „sieht“. Mischen Sie keine Zeitreihendaten und berechnen Sie keine Gruppenstatistiken für den gesamten Datensatz, bevor Sie ihn für Coaching und Checks aufteilen.
# Rating und High-N innerhalb der Gruppen
// Finden der High-k-Zeilen professional Gruppe
Hier sind zwei praktische Optionen zum Auswählen der obersten N Zeilen aus jeder Gruppe.
# Kind + head
top3 = (df.sort_values(('cat', 'rev'), ascending=(True, False))
.groupby('cat')
.head(3))
# Per-group nlargest on one metric
top3_alt = (df.groupby('cat', group_keys=False)
.apply(lambda g: g.nlargest(3, 'rev')))
// Hilfsfunktionen verwenden
Pandas bietet mehrere Hilfsfunktionen für die Rangfolge und Auswahl.
Rang – Steuert, wie Bindungen gehandhabt werden (z. B. technique='dense' oder 'first') und kann damit Perzentilränge berechnen pct=True.
df('rev_rank_in_cat') = df.groupby('cat')('rev').rank(technique='dense', ascending=False)
cumcount – Gibt die 0-basierte Place jeder Zeile innerhalb ihrer Gruppe an.
df('pos_in_store') = df.groupby('retailer').cumcount()
nth – Wählt die k-te Zeile professional Gruppe aus, ohne den gesamten DataFrame zu sortieren.
second_row = df.groupby('retailer').nth(1) # the second row current per retailer
# Broadcasting-Funktionen mit Transformation
// Durchführen einer gruppenweisen Normalisierung
Standardisieren Sie eine Metrik innerhalb jeder Gruppe, damit Zeilen über verschiedene Gruppen hinweg vergleichbar werden.
g = df.groupby('retailer')('rev')
df('rev_z') = (df('rev') - g.rework('imply')) / g.rework('std')
// Fehlende Werte imputieren
Füllen Sie fehlende Werte mit einer Gruppenstatistik. Dadurch bleiben Verteilungen oft näher an der Realität als bei der Verwendung eines globalen Füllwerts.
df('value') = df('value').fillna(df.groupby('cat')('value').rework('median'))
// Erstellen von Share-of-Group-Funktionen
Wandeln Sie rohe Zahlen für klarere Vergleiche in gruppeninterne Proportionen um.
df('rev_share_in_store') = df('rev') / df.groupby('retailer')('rev').rework('sum')
# Umgang mit Kategorien, leeren Gruppen und fehlenden Daten
// Verbessern der Geschwindigkeit mit kategorialen Typen
Wenn Ihre Schlüssel aus einem festen Satz stammen (z. B. Geschäfte, Regionen, Produktkategorien), wandeln Sie sie einmal in einen kategorialen Typ um. Das macht GroupBy Operationen schneller und speichereffizienter.
from pandas.api.varieties import CategoricalDtype
store_type = CategoricalDtype(classes=sorted(df('retailer').dropna().distinctive()), ordered=False)
df('retailer') = df('retailer').astype(store_type)
cat_type = CategoricalDtype(classes=('Grocery', 'Electronics', 'Residence', 'Clothes', 'Sports activities'))
df('cat') = df('cat').astype(cat_type)
// Nicht verwendete Kombinationen löschen
Beim Gruppieren nach kategorialen Spalten wird die Einstellung vorgenommen noticed=True schließt Kategoriepaare aus, die tatsächlich nicht in den Daten vorkommen, was zu saubereren Ausgaben mit weniger Rauschen führt.
out = df.groupby(('retailer', 'cat'), noticed=True).measurement().reset_index(identify="n")
// Gruppierung mit NaN-Schlüsseln
Machen Sie deutlich, wie Sie mit fehlenden Schlüsseln umgehen. Standardmäßig fallen Pandas aus NaN Gruppen; Behalten Sie sie nur, wenn dies Ihrem Qualitätssicherungsprozess hilft.
# Default: NaN keys are dropped
by_default = df.groupby('area').measurement()
# Maintain NaN as its personal group when you could audit lacking keys
stored = df.groupby('area', dropna=False).measurement()
# Schneller Cheatsheet
// Berechnen einer bedingten Charge professional Gruppe
# imply of a boolean is a charge
df.groupby(keys).agg(charge=('flag', 'imply'))
# or explicitly: sum(masks)/measurement
df.groupby(keys).agg(charge=('flag', lambda s: s.sum() / s.measurement))
// Berechnen eines gewichteten Mittels
df.assign(wx=df(x) * df(w))
.groupby(keys)
.apply(lambda g: g('wx').sum() / g(w).sum() if g(w).sum() else np.nan)
.rename('wavg')
// Finden der High-k professional Gruppe
(df.sort_values((key, metric), ascending=(True, False))
.groupby(key)
.head(ok))
# or
df.groupby(key, group_keys=False).apply(lambda g: g.nlargest(ok, metric))
// Berechnung wöchentlicher Kennzahlen
df.groupby((key, pd.Grouper(key='ts', freq='W')), noticed=True).agg(...)
// Durchführen einer gruppenweisen Füllung
df(col) = df(col).fillna(df.groupby(keys)(col).rework('median'))
// Berechnen des Anteils innerhalb einer Gruppe
df('share') = df(val) / df.groupby(keys)(val).rework('sum')
# Zusammenfassung
Wählen Sie zunächst den richtigen Modus für Ihre Aufgabe: Verwenden agg reduzieren, rework senden und reservieren apply für den Fall, dass Vektorisierung keine Possibility ist. Lehnen Sie sich an pd.Grouper für zeitbasierte Buckets und Rating-Helfer für High-N-Auswahlen. Indem Sie klare, vektorisierte Muster bevorzugen, können Sie Ihre Ausgaben flach, benannt und einfach zu testen halten und so sicherstellen, dass Ihre Metriken korrekt bleiben und Ihre Notebooks schnell laufen.
Josep Ferrer ist ein Analyseingenieur aus Barcelona. Er hat einen Abschluss in Physik-Ingenieurwesen und arbeitet derzeit im Bereich der Datenwissenschaft für die menschliche Mobilität. Er ist nebenberuflich als Content material-Ersteller tätig und konzentriert sich auf Datenwissenschaft und -technologie. Josep schreibt über alles, was mit KI zu tun hat, und behandelt die Anwendung der anhaltenden Explosion in diesem Bereich.
