Pandas & NumPy Academy · Lektion

apply() med GroupBy

Skicka en funktion som arbetar på flera rader till groupby().apply() för att beräkna komplexa sammanfattningar på gruppnivå som agg() inte kan uttrycka.

Lektion 2 av 413 steg

apply() med GroupBy är en gratis lektion i Pandas & NumPy Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Pandas & NumPy Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Pandas & NumPy Academy innehåller totalt 4 lektioner.

Varför GroupBy behöver apply()

Den inbyggda metoden agg() hanterar enkla aggregeringar som summa, medelvärde och antal – ett skalärt resultat per grupp. Vissa beräkningar på gruppnivå kräver däremot att hela gruppens del-DataFrame beaktas, inte bara en enskild kolumn. groupby().apply(func) skickar hela gruppens DataFrame till Er funktion och samlar in resultaten, vilket möjliggör komplexa sammanfattningar som agg() inte kan uttrycka.

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)

Returnera ett skalärt värde per grupp

När funktionen som skickas till groupby().apply() returnerar ett skalärt värde blir resultatet en Series indexerad efter gruppnycklarna – identiskt med det som agg() producerar. Den här formen är användbar när det skalära värdet kräver logik över flera kolumner, till exempel vid beräkning av förhållandet mellan intäkterna från topprodukten och gruppens totala intäkter, vilket inte kan uttryckas i en enda kolumnspecifikation för 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)

Returnera en Series per grupp

När funktionen returnerar en pd.Series får resultatet ett MultiIndex: den yttre nivån är gruppnyckeln och den inre nivån är Series-indexet. Detta är användbart för att beräkna flera statistiska mått per grupp i ett enda anrop till apply, vilket ger en sammanfattningstabell där varje grupp har flera rader med mått.

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)

Returnera en DataFrame per grupp

När funktionen returnerar en pd.DataFrame sammanfogar groupby().apply() alla del-DataFrames vertikalt. Detta är den mest kraftfulla formen: Ni kan filtrera eller omforma raderna inom varje grupp och returnera en modifierad delmängd. Ni kan till exempel behålla de två produkter som har högst intäkter inom varje region.

def top2_per_region(group):
    return group.nlargest(2, 'revenue')

top2 = df.groupby('region').apply(top2_per_region)
print(top2.reset_index(drop=True))

Beräkna Z-poäng inom grupper

Ett vanligt användningsområde för groupby().apply() är att beräkna standardisering inom grupper. I stället för att normalisera intäkterna i förhållande till alla beställningar, vilket blandar regionerna, beräknar Ni intäkternas Z-poäng inom varje region. En Z-poäng på 2 i norr innebär ”2 standardavvikelser över genomsnittet i norr” – ett mer meningsfullt jämförelsevärde än 2 standardavvikelser över det globala genomsnittet.

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)

Anpassad aggregering: winsoriserat medelvärde

Det winsoriserade medelvärdet begränsar extrema värden innan medelvärdet beräknas, vilket gör det mer robust än det vanliga medelvärdet för snedfördelade fördelningar. Den här anpassade aggregeringen kan inte uttryckas med standardfunktionerna i agg(), men är enkel att utföra med groupby().apply(): begränsa värdena vid den 5:e och 95:e percentilen inom varje grupp och beräkna sedan medelvärdet för de begränsade värdena.

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)

Anpassat rullande fönster per grupp

Rullande fönster som tillämpas på hela DataFrame ignorerar gruppgränser. Om Ni beräknar ett rullande medelvärde över tre rader i en tidsserie som växlar mellan två produkter kommer fönstret felaktigt att passera produktgränserna. Tillämpa det rullande fönstret inuti en groupby().apply() för att säkerställa att varje rullande beräkning stannar inom sin grupp – till exempel ett rullande tremånadersmedelvärde för intäkter per 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()')

Parametern include_groups (Pandas 2.2+)

I Pandas 2.2 och senare genererar groupby().apply() en FutureWarning om groupby-nycklarna finns med i den DataFrame som funktionen tar emot. Skicka med include_groups=False för att utesluta groupby-kolumnerna från den del-DataFrame som skickas till funktionen. Då undviker Ni både varningen och oavsiktliga operationer på nyckelkolumnerna i funktionskroppen.

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

Kombinera apply()-resultat med reset_index

När groupby().apply() returnerar en DataFrame per grupp får resultatet ett MultiIndex där gruppnyckeln ingår som den yttre nivån. Använd reset_index(drop=True) för att återställa indexet till ett vanligt heltalsintervall. Alternativt kan Ni använda reset_index(level=0) för att omvandla gruppnyckeln till en kolumn så att den tydligt visas i resultatet.

result = df.groupby('region').apply(top2_per_region)
print('With MultiIndex:')
print(result.head())

print('\nAfter reset_index:')
print(result.reset_index(drop=True))

När transform() bör föredras framför apply()

groupby().apply() används för komplexa beräkningar på gruppnivå som returnerar en annan form än indata. groupby().transform() används för beräkningar som lägger till en ny kolumn som är justerad efter det ursprungliga indexet – till exempel genom att sprida gruppens medelvärde till varje rad för normalisering. Använd transform när resultatet behöver ha samma form som den ursprungliga DataFrame; använd apply när resultatets form skiljer sig.

# 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']])

Prestandatips: undvik apply() för enkla aggregeringar

groupby().apply() är betydligt långsammare än groupby().agg() för enkla operationer eftersom apply() skapar ett fullständigt Python-objekt för varje grupp. För summor, medelvärden och antal ska Ni alltid använda agg(). Spara apply() till fall som faktiskt kräver hela gruppens DataFrame – villkorslogik över flera kolumner, anpassade statistiska mått eller filtrering inom grupper.

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

Snabbtest

Testa Er förståelse av dataanalysbegreppen från den här lektionen.

Lektionssammanfattning

I den här lektionen har Ni lärt Er: att returnera skalära värden, Series och DataFrames från groupby().apply(), att beräkna Z-poäng inom grupper och anpassad robust statistik samt att välja mellan apply(), agg() och transform() för operationer på gruppnivå. Härnäst utforskar vi map() och applymap() för elementvisa operationer på Series och DataFrames.

Gratis att börja

Lär dig Python med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
30
Lektioner
120

Vanliga frågor

Är lektionen ”apply() med GroupBy” gratis?

Ja – hela texten till ”apply() med GroupBy” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Pandas & NumPy Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Pandas & NumPy Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”apply() med GroupBy”?

Skicka en funktion som arbetar på flera rader till groupby().apply() för att beräkna komplexa sammanfattningar på gruppnivå som agg() inte kan uttrycka. Ni övar på Pandas & NumPy Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Pandas & NumPy Academy?

Du behöver inga förkunskaper. Utbildningen i Pandas & NumPy Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.

Hur lång tid tar lektionen ”apply() med GroupBy”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Pandas & NumPy Academy-lektionen?

Ja. Varje Pandas & NumPy Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. apply() på kolumner och rader
  2. apply() med GroupBy
  3. map() och applymap() för elementvisa operationer
  4. Metodkedjor med pipe()
← Tillbaka till Pandas & NumPy Academy