Introduzione
Quando si lavora con dati reali, spesso il problema non consiste soltanto nel leggere o filtrare un DataFrame, ma nel trasformare la sua struttura per renderla più adatta all’analisi. Un dataset può essere organizzato in formato “largo”, con molte colonne dedicate a categorie diverse, oppure in formato “lungo”, con una riga per ogni osservazione.
Pandas offre diversi strumenti per rimodellare i dati senza dover scrivere complessi cicli manuali. In questo tutorial vedremo come utilizzare principalmente:
- melt(), per trasformare un DataFrame largo in uno lungo;
- pivot(), per trasformare dati lunghi in una struttura tabellare larga;
- pivot_table(), per creare tabelle pivot con aggregazioni;
- crosstab(), per analizzare la frequenza combinata di due o più variabili.
Queste tecniche sono molto utili nella preparazione di report, nella costruzione di grafici e nell’analisi di dati provenienti da file CSV o database.
Codice completo
import pandas as pd
# Dataset iniziale in formato largo:
# ogni prodotto ha una colonna distinta per ogni trimestre
vendite_larghe = pd.DataFrame({
"prodotto": ["Laptop", "Mouse", "Tastiera", "Monitor"],
"categoria": ["Computer", "Accessori", "Accessori", "Computer"],
"Q1": [120, 450, 300, 90],
"Q2": [135, 470, 320, 110],
"Q3": [150, 510, 340, 125],
"Q4": [180, 560, 390, 140]
})
print("Dati in formato largo:")
print(vendite_larghe)
# Trasformazione in formato lungo
vendite_lunghe = vendite_larghe.melt(
id_vars=["prodotto", "categoria"],
var_name="trimestre",
value_name="quantita"
)
print("nDati in formato lungo:")
print(vendite_lunghe)
# Ricostruzione della tabella originale con pivot()
vendite_ricostruite = vendite_lunghe.pivot(
index=["prodotto", "categoria"],
columns="trimestre",
values="quantita"
).reset_index()
print("nTabella ricostruita:")
print(vendite_ricostruite)
# Dataset con più righe per prodotto e trimestre
ordini = pd.DataFrame({
"prodotto": [
"Laptop", "Laptop", "Mouse", "Mouse",
"Tastiera", "Tastiera", "Monitor", "Monitor"
],
"trimestre": [
"Q1", "Q1", "Q2", "Q2",
"Q3", "Q3", "Q4", "Q4"
],
"canale": [
"Online", "Negozio", "Online", "Negozio",
"Online", "Negozio", "Online", "Negozio"
],
"quantita": [70, 50, 280, 190, 200, 140, 80, 60]
})
# Tabella pivot con aggregazione
riepilogo = pd.pivot_table(
ordini,
index="prodotto",
columns="trimestre",
values="quantita",
aggfunc="sum",
fill_value=0,
margins=True,
margins_name="Totale"
)
print("nRiepilogo delle quantità:")
print(riepilogo)
# Tabella di frequenza tra categoria e canale
frequenze = pd.crosstab(
index=ordini["prodotto"],
columns=ordini["canale"],
margins=True,
margins_name="Totale"
)
print("nFrequenze per prodotto e canale:")
print(frequenze) Spiegazione
Dal formato largo al formato lungo con melt()
Nel formato largo, ogni variabile è spesso rappresentata da una colonna separata. Nel nostro esempio, i trimestri Q1, Q2, Q3 e Q4 sono colonne diverse. Questa struttura è leggibile per una persona, ma non sempre è la più comoda per le analisi automatiche.
Il metodo melt() raccoglie più colonne in due nuove colonne:
- var_name contiene il nome della variabile, in questo caso il trimestre;
- value_name contiene il valore associato, cioè la quantità venduta.
Il parametro id_vars indica le colonne che devono rimanere invariate. Nel codice, prodotto e categoria identificano ciascuna osservazione e non devono essere trasformate.
Il risultato è una riga per ogni combinazione prodotto-trimestre. Questo formato è particolarmente adatto a librerie di visualizzazione come Seaborn e Matplotlib, oltre che a molte operazioni di aggregazione.
Dal formato lungo al formato largo con pivot()
Il metodo pivot() esegue l’operazione inversa. Utilizza una colonna come indice delle righe, una come intestazione delle colonne e una come contenuto delle celle.
Nel nostro esempio:
- index identifica le righe con prodotto e categoria;
- columns trasforma il trimestre in intestazioni;
- values specifica quali numeri inserire nella tabella.
È importante ricordare che pivot() richiede una combinazione univoca tra indice e colonna. Se esistono più righe per lo stesso prodotto e trimestre, Pandas genera un errore perché non sa quale valore scegliere.
Aggregare con pivot_table()
Quando sono presenti duplicati, si utilizza pivot_table(). Questo metodo permette di indicare una funzione di aggregazione tramite aggfunc. Nell’esempio viene usata la funzione sum, così le quantità relative allo stesso prodotto e trimestre vengono sommate.
Il parametro fill_value=0 sostituisce con zero le combinazioni senza dati. margins=True, invece, aggiunge una riga e una colonna con i totali complessivi. Queste opzioni sono molto utili per produrre report leggibili.
Analizzare le frequenze con crosstab()
crosstab() crea una tabella di contingenza. È utile quando si vuole contare quante osservazioni appartengono a ciascuna combinazione di categorie. Nel codice viene calcolato il numero di ordini per prodotto e canale di vendita.
Per impostazione predefinita, crosstab() conta le occorrenze. Con il parametro values e una funzione di aggregazione è possibile anche sommare o analizzare una colonna numerica.
Best practice
- Scegli il formato in base all’obiettivo: il formato lungo è spesso migliore per analisi e grafici, mentre quello largo è comodo per report e riepiloghi.
- Controlla i duplicati prima di usare pivot(): usa
duplicated()per verificare se una combinazione di colonne compare più volte. - Preferisci pivot_table() quando i dati non sono univoci: puoi scegliere chiaramente come gestire i duplicati con una funzione come
sum,mean,minomax. - Assegna nomi espliciti alle colonne: nomi come
trimestreequantitarendono il codice più comprensibile di nomi generici comevariableevalue. - Verifica il risultato: dopo una trasformazione, usa
head(),shapeeinfo()per controllare struttura e dimensioni del DataFrame. - Gestisci gli indici: dopo
pivot()può essere presente un indice gerarchico. Usareset_index()se ti serve tornare a colonne normali.
Riepilogo
Rimodellare un DataFrame è una competenza fondamentale per lavorare efficacemente con Pandas. melt() converte dati larghi in dati lunghi, mentre pivot() ricostruisce una tabella larga quando le combinazioni sono univoche. Se sono presenti duplicati o se è necessaria un’aggregazione, pivot_table() è la scelta più adatta.
crosstab(), infine, permette di ottenere rapidamente tabelle di frequenza tra variabili categoriche. Combinando questi strumenti è possibile preparare dati disordinati per analisi, grafici e report senza ricorrere a elaborazioni manuali complesse.
