Pandas & NumPy Academy · Lektion

GroupBy-transformering og -filtrering

Brug transform() til at tilføje statistikker på gruppeniveau som en kolonne, og filter() til kun at beholde grupper, der opfylder en betingelse.

Lektion 4 af 413 trin

GroupBy-transformering og -filtrering er en gratis Pandas & NumPy Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Pandas & NumPy Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Pandas & NumPy Academy-kurset indeholder 4 lektioner i alt.

Ud over aggregering

Når du har lært agg(), opstår det naturlige spørgsmål: Hvad gør du, hvis du vil bevare alle oprindelige rækker, men berige dem med statistik på gruppeniveau? Eller hvis du kun vil beholde de grupper, der opfylder en betingelse? Det er her, transform() og filter() kommer ind. Disse to metoder udvider GroupBy fra simpel opsummering til feature engineering og dataudvælgelse.

Forstå transform()

transform() anvender en funktion på hver gruppe og returnerer et resultat med samme form som den oprindelige DataFrame — én værdi pr. oprindelig række. Gruppens resultat udbredes tilbage til hver række, der tilhører gruppen. Det gør metoden velegnet til at tilføje statistik på gruppeniveau som nye kolonner uden at ændre antallet af rækker.

import pandas as pd

df = pd.DataFrame({
    'dept':   ['Eng', 'HR', 'Eng', 'HR', 'Eng'],
    'salary': [90000, 60000, 95000, 62000, 88000]
})

# Add a column with each employee's department average salary
df['dept_avg'] = df.groupby('dept')['salary'].transform('mean')
print(df)
#    dept  salary    dept_avg
# 0   Eng   90000  91000.000
# 1    HR   60000  61000.000
# 2   Eng   95000  91000.000
# 3    HR   62000  61000.000
# 4   Eng   88000  91000.000

Almindelige anvendelser af transform()

Almindelige anvendelser af transform() omfatter at tilføje et gruppegennemsnit for at normalisere værdier, at tilføje en gruppesum for at beregne hver rækkes procentdel af totalen og at tilføje en grupperangering for at se, hvordan hvert medlem klarer sig i sin gruppe. Alle disse anvendelser bevarer den oprindelige form og det oprindelige indeks, så resultatet straks kan bruges sammen med de oprindelige kolonner.

# Percentage of each employee's salary within their department total
df['pct_of_dept'] = (
    df['salary'] / df.groupby('dept')['salary'].transform('sum') * 100
).round(1)
print(df[['dept', 'salary', 'pct_of_dept']])
# dept  salary  pct_of_dept
# Eng   90000        33.1
# HR    60000        49.2
# Eng   95000        34.9

Brug af en brugerdefineret funktion i transform()

Ligesom agg() accepterer transform() alle kaldelige funktioner ud over strengnavne. Funktionen modtager en Series med værdier for én gruppe og skal returnere en Series med samme længde eller en skalar, som derefter udbredes. Det mest almindelige er at returnere en skalar — hvis du returnerer en Series med en anden længde, opstår der en fejl.

# Z-score normalisation within each department
def zscore(s):
    return (s - s.mean()) / s.std()

df['salary_zscore'] = df.groupby('dept')['salary'].transform(zscore)
print(df[['dept', 'salary', 'salary_zscore']].round(2))
# dept  salary  salary_zscore
# Eng   90000          -0.51
# HR    60000          -0.71
# Eng   95000           1.03

agg() kontra transform() side om side

Den vigtigste forskel er, at agg() reducerer antallet af rækker (én pr. gruppe), mens transform() bevarer antallet af rækker (én pr. oprindelig række). Brug agg() til at opbygge en oversigtstabel. Brug transform() til at tilføje oplysninger på gruppeniveau som en ny featurekolonne i den oprindelige DataFrame.

g = df.groupby('dept')['salary']

# agg: 2 rows (one per unique dept)
print(g.agg('mean'))
# dept
# Eng    91000.0
# HR     61000.0

# transform: 5 rows (one per original row)
print(g.transform('mean'))
# 0    91000.0
# 1    61000.0
# 2    91000.0
# 3    61000.0
# 4    91000.0

Forstå filter()

filter() beholder eller forkaster hele grupper baseret på en boolsk funktion. Du angiver en funktion, der modtager en under-DataFrame for én gruppe og returnerer True (behold gruppen) eller False (fjern gruppen). Resultatet er et udsnit af den oprindelige DataFrame, som kun indeholder rækker fra de grupper, der bestod testen.

df2 = pd.DataFrame({
    'dept':   ['Eng', 'HR', 'Eng', 'HR', 'Eng', 'Legal'],
    'salary': [90000, 60000, 95000, 62000, 88000, 70000]
})

# Keep only departments with at least 2 employees
big_depts = df2.groupby('dept').filter(lambda g: len(g) >= 2)
print(big_depts)
# dept, salary rows: Eng(3) and HR(2) remain; Legal(1) dropped

Filtrering efter en samlet gruppeværdi

En meget almindelig anvendelse af filter() er at beholde grupper, hvis samlede værdi opfylder en tærskel. Du kan for eksempel kun beholde afdelinger, hvor den gennemsnitlige løn overstiger et mål, eller produktkategorier, hvor det samlede salg ligger over et minimum. På den måde kan du fjerne grupper med lav aktivitet før yderligere analyse.

# Keep only departments where average salary > 80000
high_paying = df2.groupby('dept').filter(
    lambda g: g['salary'].mean() > 80000
)
print(high_paying)
#    dept  salary
# 0   Eng   90000
# 2   Eng   95000
# 4   Eng   88000
# (HR avg is 61000, filtered out)

Kombination af transform() og filter()

Du kan anvende transform() og filter() efter hinanden for først at berige dine data og derefter indsnævre dem. Brug først filter() til at fjerne irrelevante grupper, og brug derefter transform() på det filtrerede resultat for at tilføje funktioner på gruppeniveau. Kombinationen giver dig et rent, funktionsrigt udsnit, der er klar til modellering eller rapportering.

# Step 1: keep only large departments
filtered = df2.groupby('dept').filter(lambda g: len(g) >= 2)

# Step 2: add group mean salary to the filtered result
filtered = filtered.copy()
filtered['dept_avg'] = filtered.groupby('dept')['salary'].transform('mean')
print(filtered)

transform() til fremadrettet udfyldning i grupper

transform() er også nyttig med ikke-numeriske funktioner. Et populært mønster er at udfylde manglende værdier inden for en gruppe ved hjælp af gruppens fremadrettede udfyldning eller median, hvilket er langt bedre end en global udfyldning. Angiv en lambda, der kalder fillna() på gruppens Series, så får resultatet samme indeks som den oprindelige DataFrame.

import numpy as np

df3 = pd.DataFrame({
    'dept':   ['Eng', 'Eng', 'HR', 'HR', 'Eng'],
    'salary': [90000, np.nan, 60000, np.nan, 88000]
})

# Fill NaN with the group mean
df3['salary_filled'] = df3.groupby('dept')['salary'].transform(
    lambda s: s.fillna(s.mean())
)
print(df3)

Praktisk mønster: relativ placering

Et effektivt anvendelsesområde i forretningssammenhænge er at beregne hver rækkes placering i forhold til sin gruppe. Ved at kombinere transform() med aritmetik kan du tilføje kolonner som: løn minus gruppens gennemsnit (afvigelse), løn som andel af gruppens total eller et boolesk flag for, om medarbejderen tjener mere end gruppens median. Disse funktioner er særdeles nyttige til dashboards og ML-modeller.

df['dept_total'] = df.groupby('dept')['salary'].transform('sum')
df['pct_of_total'] = (df['salary'] / df['dept_total'] * 100).round(1)
df['above_avg'] = df['salary'] > df.groupby('dept')['salary'].transform('mean')
print(df[['dept', 'salary', 'pct_of_total', 'above_avg']])

Overvejelser om ydeevne

Både transform() og filter() med indbyggede strengfunktioner er hurtige, fordi de bruger optimerede kodeveje. Når du derimod angiver en lambda eller brugerdefineret Python-funktion, skal Pandas kalde funktionen én gang pr. gruppe, hvilket kan være langsomt for data med mange grupper. For at opnå maksimal ydeevne med store datasæt bør du undersøge, om din brugerdefinerede logik kan udtrykkes med en indbygget strengfunktion i stedet.

# Slower: custom lambda (called once per group)
df['dept_mean_slow'] = df.groupby('dept')['salary'].transform(lambda s: s.mean())

# Faster: built-in string shortcut (vectorised C path)
df['dept_mean_fast'] = df.groupby('dept')['salary'].transform('mean')

# Both give identical results, but the built-in is significantly faster

Hurtig kontrol

Test din forståelse af GroupBy transform() og filter() fra denne lektion.

Opsummering af lektionen

I denne lektion har du lært, at transform() returnerer gruppestatistik, der udbredes tilbage til det oprindelige antal rækker, hvilket gør metoden velegnet til at tilføje funktioner på gruppeniveau; at filter() beholder eller fjerner hele grupper baseret på en boolsk betingelse; og at en kombination af begge metoder lader dig opbygge rige, filtrerede datasæt til efterfølgende analyse. Dernæst undersøger vi, hvordan du kombinerer DataFrames med pd.concat.

Gratis at komme i gang

Lær Python med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
30
Lektioner
120

Ofte stillede spørgsmål

Er lektionen “GroupBy-transformering og -filtrering” gratis?

Ja — hele teksten til “GroupBy-transformering og -filtrering” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Pandas & NumPy Academy-kurset, skal du opgradere til CoddyKit PRO. Pandas & NumPy Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “GroupBy-transformering og -filtrering”?

Brug transform() til at tilføje statistikker på gruppeniveau som en kolonne, og filter() til kun at beholde grupper, der opfylder en betingelse. Du øver dig i Pandas & NumPy Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Pandas & NumPy Academy?

Der kræves ingen tidligere erfaring. Pandas & NumPy Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “GroupBy-transformering og -filtrering”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Pandas & NumPy Academy-lektion?

Ja. Alle Pandas & NumPy Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Mønsteret split-apply-combine
  2. GroupBy med én eller flere nøgler
  3. Metoden agg()
  4. GroupBy-transformering og -filtrering
← Tilbage til Pandas & NumPy Academy