apply() met GroupBy
Geef een functie voor meerdere rijen door aan groupby().apply() om complexe samenvattingen op groepsniveau te berekenen die agg() niet kan uitdrukken.
apply() met GroupBy is een gratis Pandas & NumPy Academy-les op CoddyKit. Dit is les 2 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Pandas & NumPy Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Pandas & NumPy Academy bevat in totaal 4 lessen.
Waarom GroupBy apply() nodig heeft
De ingebouwde methode agg() verwerkt eenvoudige aggregaties zoals sum, mean en count — één scalaire uitvoer per groep. Voor sommige berekeningen op groepsniveau moet je echter naar het volledige sub-DataFrame van de groep kijken, niet alleen naar één kolom. groupby().apply(func) geeft het volledige DataFrame van de groep door aan je functie en verzamelt de resultaten, zodat je complexe samenvattingen kunt maken die je niet met agg() kunt uitdrukken.
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)Eén scalaire waarde per groep retourneren
Wanneer de functie die je aan groupby().apply() doorgeeft een scalaire waarde retourneert, is het resultaat een Series met de groepssleutels als index — identiek aan wat agg() oplevert. Deze vorm is handig wanneer de scalaire waarde logica over meerdere kolommen vereist, zoals het berekenen van de verhouding tussen de omzet van het best verkopende product en de totale groepsomzet; dat kun je niet uitdrukken in één kolomspecificatie van agg().
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)Een Series per groep retourneren
Wanneer de functie een pd.Series retourneert, heeft het resultaat een MultiIndex: het buitenste niveau is de groepssleutel en het binnenste niveau is de index van de Series. Dit is handig om meerdere statistieken per groep te berekenen in één aanroep van apply, waardoor een overzichtstabel ontstaat waarin elke groep meerdere rijen met meetwaarden heeft.
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)Een DataFrame per groep retourneren
Wanneer de functie een pd.DataFrame retourneert, voegt groupby().apply() alle sub-DataFrames verticaal samen. Dit is de krachtigste vorm: je kunt er de rijen binnen elke groep mee filteren of transformeren en een aangepaste subset retourneren. Je kunt bijvoorbeeld alleen de twee producten met de hoogste omzet binnen elke regio behouden.
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 binnen groepen berekenen
Een veelgebruikte toepassing van groupby().apply() is standaardiseren binnen groepen. Normaliseer de omzet niet ten opzichte van alle orders, want dan vermeng je regio's; bereken in plaats daarvan de Z-score van de omzet binnen elke regio. Een Z-score van 2 in het noorden betekent "2 standaardafwijkingen boven het gemiddelde van het noorden" — een betekenisvollere referentie dan 2 standaardafwijkingen boven het algemene gemiddelde.
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)Aangepaste aggregatie: Winsorised gemiddelde
Het Winsorised gemiddelde kapt extreme waarden af voordat het gemiddelde wordt berekend, waardoor het robuuster is dan het gewone gemiddelde bij scheve verdelingen. Deze aangepaste aggregatie kun je niet uitdrukken met standaardfuncties van agg(), maar wel eenvoudig met groupby().apply(): kap binnen elke groep af op het 5e en 95e percentiel en bereken vervolgens het gemiddelde van de afgekapt waarden.
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)Aangepast voortschrijdend venster per groep
Voortschrijdende vensters die op het volledige DataFrame worden toegepast, houden geen rekening met groepsgrenzen. Als je een voortschrijdend gemiddelde over drie rijen berekent voor een tijdreeks waarin twee producten elkaar afwisselen, overschrijdt het venster onterecht de productgrenzen. Pas het voortschrijdende venster toe binnen groupby().apply() om ervoor te zorgen dat elke berekening binnen de eigen groep blijft — bijvoorbeeld een voortschrijdend omzetgemiddelde over drie maanden per regio.
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()')De parameter include_groups (Pandas 2.2+)
In Pandas 2.2 en hoger geeft groupby().apply() een FutureWarning als de sleutels van groupby voorkomen in het DataFrame dat de functie ontvangt. Geef include_groups=False door om de groupby-kolommen uit te sluiten van het sub-DataFrame dat aan de functie wordt doorgegeven. Zo voorkom je zowel de waarschuwing als onbedoelde bewerkingen op de sleutelkolommen binnen de functie.
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+')Resultaten van apply() combineren met reset_index
Wanneer groupby().apply() per groep een DataFrame retourneert, heeft het resultaat een MultiIndex met de groepssleutel als buitenste niveau. Gebruik reset_index(drop=True) om de index terug te brengen tot een eenvoudige reeks gehele getallen. Je kunt ook reset_index(level=0) gebruiken om de groepssleutel naar een kolom te promoveren, zodat deze expliciet in de uitvoer staat.
result = df.groupby('region').apply(top2_per_region)
print('With MultiIndex:')
print(result.head())
print('\nAfter reset_index:')
print(result.reset_index(drop=True))Wanneer je transform() verkiest boven apply()
groupby().apply() is bedoeld voor complexe berekeningen op groepsniveau die een andere vorm opleveren dan de invoer. groupby().transform() is bedoeld voor berekeningen die een nieuwe kolom toevoegen die is uitgelijnd met de oorspronkelijke index — bijvoorbeeld het groepsgemiddelde naar elke rij verspreiden voor normalisatie. Gebruik transform wanneer je het resultaat in dezelfde vorm als het oorspronkelijke DataFrame nodig hebt; gebruik apply wanneer de vorm van het resultaat verschilt.
# 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']])Prestatietip: vermijd apply() voor eenvoudige aggregaties
groupby().apply() is aanzienlijk trager dan groupby().agg() voor eenvoudige bewerkingen, omdat apply() voor elke groep een volledig Python-object maakt. Gebruik voor sommen, gemiddelden en aantallen altijd agg(). Bewaar apply() voor situaties waarvoor je echt het volledige groeps-DataFrame nodig hebt — logica met voorwaarden over meerdere kolommen, aangepaste statistieken of filteren binnen groepen.
# 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))Korte controle
Test je begrip van de concepten voor gegevensanalyse uit deze les.
Samenvatting van de les
In deze les heb je geleerd: scalaire waarden, Series en DataFrames retourneren vanuit groupby().apply(), Z-scores binnen groepen en aangepaste robuuste statistieken berekenen en kiezen tussen apply(), agg() en transform() voor bewerkingen op groepsniveau. Hierna bekijken we map() en applymap() voor elementgewijze bewerkingen op Series en DataFrames.
Leer Python met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 30
- Lessen
- 120
Veelgestelde vragen
Is de les “apply() met GroupBy” gratis?
Ja — de volledige tekst van “apply() met GroupBy” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Pandas & NumPy Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Pandas & NumPy Academy bevat in totaal 4 lessen.
Wat leer ik in “apply() met GroupBy”?
Geef een functie voor meerdere rijen door aan groupby().apply() om complexe samenvattingen op groepsniveau te berekenen die agg() niet kan uitdrukken. Je oefent met Pandas & NumPy Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Pandas & NumPy Academy te beginnen?
Ervaring vooraf is niet nodig. Pandas & NumPy Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.
Hoe lang duurt de les “apply() met GroupBy”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Pandas & NumPy Academy?
Ja. Elke les over Pandas & NumPy Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- apply() op kolommen en rijen
- apply() met GroupBy
- map() en applymap() voor elementgewijze bewerkingen
- Method chaining met pipe()