Trasformazione e filtro con GroupBy
Usi transform() per aggiungere a una colonna statistiche a livello di gruppo e filter() per mantenere solo i gruppi che soddisfano una condizione.
Trasformazione e filtro con GroupBy è una lezione Pandas & NumPy Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Pandas & NumPy Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Pandas & NumPy Academy include 4 lezioni in totale.
Oltre l'aggregazione
Dopo aver acquisito dimestichezza con agg(), la domanda naturale è: cosa fare se si desidera mantenere tutte le righe originali arricchendole con statistiche a livello di gruppo? Oppure mantenere solo i gruppi che soddisfano una condizione? È qui che entrano in gioco transform() e filter(). Questi due metodi estendono GroupBy oltre il semplice riepilogo, introducendolo nell'ingegneria delle feature e nella selezione dei dati.
Capire transform()
transform() applica una funzione a ogni gruppo e restituisce un risultato con la stessa forma del DataFrame originale, ovvero un valore per ogni riga originale. Il risultato del gruppo viene ridistribuito a ogni riga appartenente a quel gruppo. Questo lo rende ideale per aggiungere statistiche a livello di gruppo come nuove colonne senza modificare il numero di righe.
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.000Casi d'uso comuni di transform()
Tra gli usi comuni di transform() vi sono: aggiungere la media del gruppo per normalizzare i valori, aggiungere la somma del gruppo per calcolare la percentuale del totale rappresentata da ogni riga e aggiungere il rango nel gruppo per confrontare ogni elemento con gli altri del proprio gruppo. Tutte queste operazioni mantengono la forma e l'indice originali, quindi il risultato può essere usato immediatamente insieme alle colonne originali.
# 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.9Usare una funzione personalizzata in transform()
Come agg(), anche transform() accetta qualsiasi funzione chiamabile, oltre ai nomi stringa. La funzione riceve una Series di valori per un gruppo e deve restituire una Series della stessa lunghezza oppure uno scalare, che viene poi ridistribuito. Restituire uno scalare è il caso d'uso più comune; restituire una Series di lunghezza diversa genera un errore.
# 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.03agg() e transform() a confronto
La differenza fondamentale è la seguente: agg() riduce il numero di righe, una per gruppo, mentre transform() mantiene il numero di righe, una per ogni riga originale. Usi agg() per creare una tabella riepilogativa. Usi transform() per aggiungere informazioni a livello di gruppo come nuova colonna nel DataFrame originale.
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.0Capire filter()
filter() mantiene o scarta interi gruppi in base a una funzione booleana. Si passa una funzione che riceve un sotto-DataFrame relativo a un gruppo e restituisce True per mantenere il gruppo oppure False per eliminarlo. Il risultato è un sottoinsieme del DataFrame originale contenente solo le righe dei gruppi che hanno superato il test.
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) droppedFiltrare in base al valore aggregato del gruppo
Un uso molto comune di filter() consiste nel mantenere i gruppi il cui valore aggregato soddisfa una soglia. Ad esempio, può mantenere solo i reparti in cui lo stipendio medio supera un obiettivo oppure solo le categorie di prodotto con vendite totali superiori a un minimo. In questo modo può rimuovere i gruppi con pochi dati prima di procedere con ulteriori analisi.
# 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)Combinare transform() e filter()
È possibile applicare transform() e filter() in sequenza per arricchire i dati e poi restringerli. Utilizzi prima filter() per rimuovere i gruppi irrilevanti, quindi applichi transform() al risultato filtrato per aggiungere feature a livello di gruppo. La combinazione produce un sottoinsieme pulito e ricco di feature, pronto per la modellazione o la reportistica.
# 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() per il riempimento in avanti nei gruppi
transform() è utile anche con funzioni non numeriche. Un approccio diffuso consiste nel riempire i valori mancanti all'interno di un gruppo usando il riempimento in avanti o la mediana del gruppo, soluzione molto più efficace rispetto a un riempimento globale. Passi una lambda che chiama fillna() sulla Series del gruppo: il risultato avrà lo stesso indice del DataFrame originale.
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)Approccio pratico: posizione relativa
Un potente caso d'uso aziendale consiste nel calcolare la posizione di ogni riga rispetto al proprio gruppo. Combinando transform() con operazioni aritmetiche, può aggiungere colonne come: stipendio meno la media del gruppo (scostamento), stipendio come frazione del totale del gruppo oppure un flag booleano che indica se il dipendente guadagna più della mediana del gruppo. Queste feature sono estremamente utili per dashboard e modelli ML.
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']])Considerazioni sulle prestazioni
Sia transform() sia filter(), quando usati con funzioni stringa integrate, sono veloci perché sfruttano percorsi di esecuzione ottimizzati. Tuttavia, quando si passa una lambda o una funzione Python personalizzata, Pandas deve chiamare quella funzione una volta per gruppo, operazione che può essere lenta su dati con molti gruppi. Per ottenere le massime prestazioni con dataset di grandi dimensioni, verifichi se la logica personalizzata può essere espressa usando invece una funzione stringa integrata.
# 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 fasterVerifica rapida
Verifichi la Sua comprensione di transform() e filter() di GroupBy presentati in questa lezione.
Riepilogo della lezione
In questa lezione ha imparato che transform() restituisce statistiche di gruppo ridistribuite fino al numero di righe originale, risultando ideale per aggiungere feature a livello di gruppo; che filter() mantiene o rimuove interi gruppi in base a una condizione booleana; e che la combinazione dei due metodi consente di creare dataset ricchi e filtrati per le analisi successive. Nella prossima lezione esploreremo come combinare i DataFrame usando pd.concat.
Impara Python con un tutor IA — gratis
Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.
- Corsi
- 30
- Lezioni
- 120
Domande Frequenti
La lezione «Trasformazione e filtro con GroupBy» è gratuita?
Sì — il testo completo di «Trasformazione e filtro con GroupBy» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Pandas & NumPy Academy, passa a CoddyKit PRO. Il corso Pandas & NumPy Academy include 4 lezioni in totale.
Cosa imparerò in «Trasformazione e filtro con GroupBy»?
Usi transform() per aggiungere a una colonna statistiche a livello di gruppo e filter() per mantenere solo i gruppi che soddisfano una condizione. Eserciti Pandas & NumPy Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Pandas & NumPy Academy?
Non è richiesta alcuna esperienza precedente. Pandas & NumPy Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Trasformazione e filtro con GroupBy»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Pandas & NumPy Academy?
Sì. Ogni lezione Pandas & NumPy Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Il pattern Split-Apply-Combine
- GroupBy con una o più chiavi
- Il metodo agg()
- Trasformazione e filtro con GroupBy