Pronto a tuffarti nel mondo affascinante (e a volte un po’ caotico) del Machine Learning? Se stai iniziando a esplorare questo campo, avrai sicuramente sentito parlare di Pandas, una libreria Python che è praticamente il coltellino svizzero per chiunque lavori con i dati. Pensa ai dati come agli ingredienti di una ricetta complessa (il tuo modello di ML): se gli ingredienti non sono di qualità o preparati nel modo giusto, il risultato finale… beh, diciamo che potrebbe non essere stellato!
Pandas ci aiuta proprio in questo: a prendere dati grezzi, spesso disordinati, e a trasformarli in qualcosa di pulito, strutturato e pronto per essere “digerito” dagli algoritmi di Machine Learning. Senza una buona preparazione dei dati (quella che in gergo si chiama data preprocessing e feature engineering), anche l’algoritmo più sofisticato rischia di fare cilecca.
Allora, sei pronto a scoprire quali sono i “ferri del mestiere” più importanti che Pandas ci offre? Prendendo spunto dall’immagine che hai condiviso, esploriamo insieme questi metodi, cercando di capire perché sono così utili e come usarli con qualche esempio pratico. Mettiti comodo, sarà un viaggio interessante!
Data Preprocessing: La Prima “Annusata” ai Dati
Prima di iniziare a pulire o trasformare, dobbiamo capire con cosa abbiamo a che fare. È come entrare in una stanza nuova: ti guardi intorno, cerchi di capire com’è fatta, no? Ecco, questi comandi servono proprio a questo.
df.head()
edf.tail()
: Vuoi dare una sbirciatina veloce alle prime (head) o alle ultime (tail) righe del tuo dataset? Questi sono i comandi perfetti. Utili per avere un’idea immediata della struttura e dei valori.import pandas as pd # Immagina di avere un DataFrame chiamato 'df' caricato da un file CSV # Visualizza le prime 5 righe print(df.head()) # Visualizza le ultime 3 righe print(df.tail(3))
df.info()
: Questo è come chiedere la “carta d’identità” del tuo DataFrame. Ti dice quante righe ci sono, i nomi delle colonne, il tipo di dati in ogni colonna (numeri, testo, date…) e quanti valori non nulli ci sono. Fondamentale per scovare subito eventuali colonne “problematiche” con molti dati mancanti o tipi di dati sbagliati.print(df.info())
df.describe()
: Se hai colonne numeriche, questo comando è oro! Ti fornisce statistiche descrittive fondamentali come conteggio, media, deviazione standard, minimo, massimo e i percentili (25°, 50° – la mediana, 75°). Ti aiuta a capire la distribuzione dei tuoi dati numerici.# Mostra statistiche descrittive per le colonne numeriche print(df.describe())
df.shape
: Semplicissimo ma vitale. Ti restituisce una tupla con (numero di righe, numero di colonne). Ti dà subito le dimensioni del tuo campo di battaglia.print(f"Il DataFrame ha {df.shape[0]} righe e {df.shape[1]} colonne.")
df.isnull().sum()
: Forse uno dei comandi più usati all’inizio. Conta quanti valori mancanti (NaN – Not a Number) ci sono per ogni colonna. È il primo passo per capire dove dovrai intervenire nella fase di pulizia.
print("Valori mancanti per colonna:") print(df.isnull().sum())
loc[]
usa le etichette (nomi delle righe/colonne). Esempio:df.loc[5, 'NomeColonna']
seleziona il valore nella riga con indice (etichetta) 5 e nella colonna ‘NomeColonna’.iloc[]
usa gli indici posizionali (numeri interi, partendo da 0). Esempio:df.iloc[5, 0]
seleziona il valore nella sesta riga (indice 5) e nella prima colonna (indice 0). Sono fondamentali per filtrare, estrarre sottoinsiemi di dati o modificare valori specifici.df.loc[]
edf.iloc[]
: Servono per selezionare dati specifici. La differenza chiave?df.at[]
edf.iat[]
: Simili aloc
eiloc
, ma ottimizzati per accedere a un singolo valore specifico in modo molto rapido.at[]
usa le etichette,iat[]
usa gli indici posizionali.
Data Cleaning and Transform: Facciamo Pulizia e Mettiamo Ordine!
Ok, ora che conosciamo meglio i nostri dati, è il momento di rimboccarsi le maniche. Dati sporchi o nel formato sbagliato possono mandare all’aria il nostro modello. Ricorda il detto: “Garbage In, Garbage Out”!
df.dropna()
: Il modo più diretto per gestire i valori mancanti: eliminarli! Puoi decidere se eliminare le intere righe (axis=0
, default) o le colonne (axis=1
) che contengono NaN. Attenzione: usarlo senza criterio può farti perdere molti dati preziosi!# Elimina tutte le righe con almeno un valore NaN df_pulito = df.dropna() # Elimina solo le colonne che hanno TUTTI valori NaN df_pulito_col = df.dropna(axis=1, how='all')
df.fillna()
: Un approccio più “gentile”. Invece di eliminare, riempi i valori mancanti. Puoi usare un valore fisso (es. 0), la media (df['colonna'].mean()
), la mediana (df['colonna'].median()
) o la moda (df['colonna'].mode()[0]
) della colonna, oppure metodi più sofisticati come il forward fill (method='ffill'
) o backward fill (method='bfill'
).# Riempi i NaN nella colonna 'Eta' con la media dell'età media_eta = df['Eta'].mean() df['Eta'].fillna(media_eta, inplace=True) # inplace=True modifica il DataFrame originale # Riempi tutti i NaN del DataFrame con 0 df.fillna(0, inplace=True)
df.replace()
: Serve per sostituire valori specifici con altri valori. Utile per correggere errori di battitura, standardizzare categorie (es. sostituire ‘USA’ e ‘Stati Uniti’ con ‘US’).# Sostituisci 'Maschio' con 'M' e 'Femmina' con 'F' nella colonna 'Genere' df['Genere'].replace({'Maschio': 'M', 'Femmina': 'F'}, inplace=True)
df.drop_duplicates()
: Elimina le righe duplicate. Puoi specificare un sottoinsieme di colonne su cui basare il controllo delle duplicazioni. Essenziale per non dare “peso” eccessivo a osservazioni identiche.# Elimina righe completamente duplicate df.drop_duplicates(inplace=True) # Elimina righe duplicate basandosi solo sulle colonne 'ID_Utente' e 'Data' df.drop_duplicates(subset=['ID_Utente', 'Data'], keep='first', inplace=True) # keep='first' tiene la prima occorrenza
df.apply()
: Una funzione potentissima! Ti permette di applicare una funzione (che puoi definire tu stesso, anche conlambda
) a ogni riga (axis=1
) o colonna (axis=0
) del DataFrame. Ottima per trasformazioni complesse che non hanno un metodo Pandas dedicato.# Crea una nuova colonna 'Doppio_Valore' applicando una lambda alla colonna 'Valore' df['Doppio_Valore'] = df['Valore'].apply(lambda x: x * 2)
pd.get_dummies()
: Fondamentale per il Machine Learning! Molti algoritmi non capiscono le variabili testuali (categoriche). Questa funzione converte le variabili categoriche in variabili “dummy” o “indicator” (formato one-hot encoding). In pratica, crea nuove colonne binarie (0 o 1) per ogni categoria presente nella colonna originale.# Trasforma la colonna 'Citta' in variabili dummy df_dummies = pd.get_dummies(df, columns=['Citta'], drop_first=True) # drop_first=True evita multicollinearità print(df_dummies.head())
df.astype()
: Cambia il tipo di dati di una o più colonne. Utile se una colonna numerica è stata letta come testo (object) o viceversa, o se vuoi convertire numeri interi in decimali (float) per calcoli più precisi.# Converti la colonna 'Prezzo_str' (che è testo) in un numero decimale df['Prezzo_num'] = df['Prezzo_str'].astype(float)
df.rename()
: Rinomina le etichette degli assi (nomi delle colonne o indici delle righe). Utile per avere nomi di colonna più chiari o standardizzati.# Rinomina la colonna 'vecchio_nome' in 'nuovo_nome' df.rename(columns={'vecchio_nome': 'nuovo_nome'}, inplace=True)
df.sort_values()
edf.sort_index()
: Ordinano il DataFrame.sort_values()
ordina in base ai valori di una o più colonne, mentresort_index()
ordina in base all’indice (etichette delle righe).
Feature Engineering: L’Arte di Creare Informazione Utile
Qui le cose si fanno creative! La feature engineering consiste nel creare nuove feature (colonne, variabili) a partire da quelle esistenti, con l’obiettivo di fornire al modello informazioni più rilevanti e predittive.
df.pivot_table()
: Crea una tabella pivot in stile spreadsheet. È incredibilmente potente per riassumere e aggregare dati, mostrando relazioni tra diverse variabili categoriche e numeriche.# Crea una tabella pivot che mostra le vendite medie per Regione e Categoria Prodotto pivot = pd.pivot_table(df, values='Vendite', index='Regione', columns='Categoria', aggfunc='mean') print(pivot)
cut()
divide i dati in bin di uguale ampiezza.qcut()
divide i dati in bin con (approssimativamente) lo stesso numero di osservazioni (quantili).pd.cut()
epd.qcut()
: Servono per “discretizzare” variabili continue, cioè dividerle in intervalli (bin). Utile per trasformare età in fasce d’età, reddito in classi di reddito, ecc.pd.to_datetime()
edf.resample()
: Essenziali per lavorare con dati temporali (time series).to_datetime()
converte colonne di testo o numeri che rappresentano date/orari nel formato datetime specifico di Pandas, che permette poi estrazioni e calcoli temporali.resample()
è fantastico per cambiare la frequenza dei dati temporali (es. da giornaliera a mensile) applicando una funzione di aggregazione (somma, media…). Richiede che l’indice del DataFrame sia di tipo datetime.
# Converti la colonna 'Data_str' in formato datetime e mettila come indice df['Data'] = pd.to_datetime(df['Data_str']) df.set_index('Data', inplace=True) # Calcola le vendite medie mensili vendite_mensili = df['Vendite'].resample('M').mean() # 'M' sta per Month End print(vendite_mensili) # Estrai l'anno e il giorno della settimana dalla data (dopo to_datetime) df['Anno'] = df.index.year df['Giorno_Settimana'] = df.index.dayofweek # Lunedì=0, Domenica=6
str.extract()
usa espressioni regolari (regex) per estrarre parti specifiche di una stringa in una nuova colonna (es. estrarre un codice numerico da un testo).str.split()
divide una stringa in base a un delimitatore, creando spesso più colonne o una lista.df['col'].str.extract()
edf['col'].str.split()
: Per lavorare con colonne di testo (stringhe).
Data Aggregation and Grouping: Riassumere e Confrontare Gruppi
Spesso, nel Machine Learning e nell’analisi dati, non siamo interessati solo ai singoli dati, ma a come si comportano i gruppi di dati. Ad esempio, le vendite medie per regione, il comportamento degli utenti per fascia d’età, ecc.
-
- Split: Divide i dati in gruppi.
- Apply: Applica una funzione (media, somma, conteggio…) a ciascun gruppo.
- Combine: Combina i risultati in una nuova struttura dati (spesso un DataFrame o una Series).
df.groupby()
: Il re delle aggregazioni! Permette di raggruppare le righe del DataFrame basandosi sui valori di una o più colonne. Da solo non fa molto, ma diventa potentissimo se combinato con funzioni di aggregazione. Il processo è spesso descritto come “Split-Apply-Combine”:
# Calcola le vendite medie per ogni 'Regione' vendite_medie_regione = df.groupby('Regione')['Vendite'].mean() print(vendite_medie_regione) # Calcola statistiche multiple (somma e media) per 'Vendite' e 'Quantita' raggruppando per 'Regione' e 'Categoria' statistiche_aggregate = df.groupby(['Regione', 'Categoria']).agg({ 'Vendite': ['sum', 'mean'], 'Quantita': 'mean' }) print(statistiche_aggregate)
df.agg()
: Abbreviazione diaggregate
. Spesso usata insieme agroupby()
per applicare diverse funzioni di aggregazione a diverse colonne contemporaneamente, come visto nell’esempio sopra.df.transform()
: Simile aapply()
dopo ungroupby()
, ma con una differenza cruciale: restituisce una Series o DataFrame con lo stesso indice dell’originale. È utile quando vuoi creare una nuova colonna basata su un calcolo di gruppo (es. sottrarre la media del gruppo da ogni valore del gruppo, per centrare i dati all’interno di ciascun gruppo).# Calcola la media delle vendite per regione media_vendite_regione = df.groupby('Regione')['Vendite'].transform('mean') # Crea una nuova colonna con la differenza tra le vendite e la media della sua regione df['Vendite_vs_MediaRegione'] = df['Vendite'] - media_vendite_regione print(df[['Regione', 'Vendite', 'Vendite_vs_MediaRegione']].head())
df.pivot()
: Simile apivot_table
, ma più semplice. Serve a “rimodellare” i dati spostando valori unici di una colonna nelle nuove colonne. Non esegue aggregazioni, quindi funziona solo se le combinazioni diindex
ecolumns
sono uniche.-
rolling()
: Calcola la funzione su una finestra di dimensione fissa che “scorre” sui dati (es. media mobile a 7 giorni).expanding()
: Calcola la funzione considerando tutti i dati dall’inizio fino al punto corrente (es. somma cumulativa).ewm()
(Exponentially Weighted Moving): Simile arolling
, ma dà più peso ai dati più recenti (es. media mobile esponenziale).Funzioni Finestra (Window Functions):df.rolling()
,df.expanding()
,df.ewm()
: Queste sono potentissime, specialmente per le serie temporali. Permettono di eseguire calcoli su una “finestra” mobile di dati.
# Calcola la media mobile a 3 periodi delle vendite (assicurati che i dati siano ordinati per tempo!) df['Vendite_MA3'] = df['Vendite'].rolling(window=3).mean() # Calcola la somma cumulativa delle quantità df['Quantita_Cumulativa'] = df['Quantita'].expanding().sum() # Calcola la media mobile esponenziale delle vendite df['Vendite_EWM'] = df['Vendite'].ewm(span=3).mean() # span è un modo per definire il decadimento
Qualche Consiglio Pratico e Riflessioni Finali
- Import Standard: Quasi universalmente, Pandas si importa così:
import pandas as pd
. Ti risparmia un sacco di battiture! - Installazione: Se non ce l’hai, è semplicissimo: apri il tuo terminale o prompt dei comandi e digita
pip install pandas
. inplace=True
: Molti metodi Pandas (comefillna
,dropna
,rename
) hanno un parametroinplace
. Se impostato aTrue
, modificano direttamente il DataFrame originale. SeFalse
(default), restituiscono una nuova copia del DataFrame con le modifiche. Fai attenzione:inplace=True
può essere comodo ma rende più difficile tracciare le modifiche se non stai attento. Spesso è meglio assegnare il risultato a una nuova variabile o sovrascrivere quella vecchia (df = df.dropna()
).- La Pratica Rende Perfetti: Leggere è utile, ma il modo migliore per imparare Pandas è… usarlo! Prendi un dataset che ti interessa (ce ne sono tantissimi open source su siti come Kaggle o UCI Machine Learning Repository) e inizia a esplorarlo e pulirlo usando questi comandi. Prova a porti delle domande sui dati e a usare Pandas per trovare le risposte.
Come vedi, Pandas è una libreria incredibilmente ricca e versatile. Questi sono solo alcuni dei metodi più comuni e importanti per il Machine Learning, ma ce ne sono molti altri. Padroneggiare la manipolazione dei dati con Pandas è un passo fondamentale per diventare un buon Data Scientist o ML Engineer. Non è solo una questione tecnica, è quasi un’arte: capire i dati, pulirli, trasformarli e modellarli per estrarre il massimo valore.
Quindi, cosa aspetti? È ora di “sporcarsi le mani” con qualche DataFrame! Buon divertimento con Pandas!