Un foglio Excel pieno di colonne, valori mancanti e date incoerenti può trasformarsi rapidamente in un problema difficile da gestire. Con Python e pandas posso importare i dati, pulirli, unirli e ricavare analisi ripetibili senza affidarmi a operazioni manuali. Qui mostro un flusso pratico, dagli oggetti fondamentali fino ai limiti da conoscere quando i dataset diventano grandi.
La strada più efficace per analizzare dati con Python
- DataFrame è la struttura principale per lavorare con dati tabellari.
- Con read_csv() e funzioni simili si importano file CSV, Excel, JSON, SQL e Parquet.
- La qualità dell’analisi dipende soprattutto da pulizia, tipi di dato e valori mancanti.
- groupby(), merge() e filtri coprono gran parte delle esigenze di analisi aziendale.
- Per dataset molto grandi servono lettura a blocchi, colonne selezionate o strumenti distribuiti.

Che cos’è pandas e perché è così utile nella data science
Pandas è una libreria open source costruita per la manipolazione e l’analisi dei dati. La sua forza non sta soltanto nel numero di funzioni disponibili, ma nel modo in cui rende leggibili operazioni che altrimenti richiederebbero molte righe di codice.
Il suo oggetto centrale è il DataFrame, una tabella con righe e colonne, simile a un foglio di calcolo ma più adatta a procedure automatiche e ripetibili. Una colonna può essere numerica, testuale, booleana o temporale, mentre l’indice identifica le righe e permette selezioni più precise.
Io lo considero soprattutto uno strumento di preparazione. Prima di costruire un grafico, un modello predittivo o una dashboard, bisogna capire se i dati sono completi, coerenti e correttamente interpretati. In questa fase pandas offre un equilibrio molto efficace tra semplicità per chi inizia e profondità per chi lavora su progetti professionali.
| Oggetto | A cosa serve | Esempio pratico |
|---|---|---|
| Series | Una singola sequenza di valori con indice | La colonna dei ricavi |
| DataFrame | Una tabella composta da più colonne | Vendite, clienti e date |
| Index | Identificare righe e intervalli | Un codice cliente o una data |
Come installare pandas e iniziare con un dataset reale
Per installare la libreria uso un ambiente virtuale dedicato al progetto. È una pratica semplice, ma evita che aggiornamenti di altri lavori modifichino le dipendenze e rendano il codice difficile da riprodurre.
python -m venv .venv
source .venv/bin/activate
pip install pandas
Su Windows cambia il comando di attivazione dell’ambiente, mentre il comando di installazione resta sostanzialmente lo stesso. In un progetto condiviso conviene salvare le dipendenze in un file come requirements.txt, così ogni collaboratore può ricreare lo stesso ambiente.
Il primo caricamento può essere molto semplice:
import pandas as pd
df = pd.read_csv("vendite.csv")
print(df.head())
print(df.info())
print(df.describe())
Le tre istruzioni finali hanno funzioni diverse. head() mostra un’anteprima, info() aiuta a controllare colonne e valori mancanti, mentre describe() riassume le variabili numeriche. Io non salto mai questo controllo iniziale: molti errori nascono da una colonna numerica importata come testo o da date lette in modo errato.
La stessa logica vale per altre fonti. Pandas mette a disposizione funzioni con prefisso read_ per CSV, Excel, JSON, database e Parquet. La scelta dipende dal formato e dalle dimensioni del file, non da una presunta superiorità universale di una singola opzione.
Come esplorare e pulire i dati senza alterarne il significato
La pulizia non significa cancellare tutto ciò che sembra anomalo. Significa capire se un valore è davvero errato, se rappresenta un caso particolare o se manca per una ragione precisa. Prima di modificare il DataFrame, controllo sempre duplicati, tipi di dato, valori nulli e distribuzioni delle variabili.
df.isna().sum()
df.duplicated().sum()
df["categoria"].value_counts(dropna=False)
Per selezionare righe e colonne preferisco loc quando uso nomi e condizioni, mentre ricorro a iloc quando mi servono posizioni numeriche.
clienti_attivi = df.loc[df["stato"] == "attivo"]
selezione = df.loc[:, ["data", "categoria", "ricavo"]]
prime_righe = df.iloc[:10, :3]
Con i valori mancanti non applico automaticamente un’unica strategia. Posso rimuovere le righe con dropna(), sostituire valori con fillna() oppure lasciare i dati invariati se l’assenza è informativa. Sostituire tutti i nulli con zero, per esempio, può falsare una media e trasformare “dato non disponibile” in “nessuna vendita”.
df["ricavo"] = df["ricavo"].fillna(0)
df["data"] = pd.to_datetime(df["data"], errors="coerce")
df = df.drop_duplicates()
Il parametro errors="coerce" converte le date non riconosciute in valori mancanti. È utile per scoprire righe problematiche, ma va usato con attenzione: se non si controllano i risultati, si rischia di nascondere errori di formattazione.
Le operazioni che trasformano una tabella in analisi
Una volta puliti i dati, il passaggio più utile consiste nel raggruppare e aggregare. Con groupby() divido le righe per una o più categorie e calcolo somme, medie, conteggi o altri indicatori.
report = (
df.groupby("categoria", as_index=False)
.agg(
ricavo_totale=("ricavo", "sum"),
ordine_medio=("ricavo", "mean"),
numero_ordini=("id_ordine", "nunique")
)
.sort_values("ricavo_totale", ascending=False)
)
Questo schema è alla base di molti report commerciali. Non mi limito però a guardare il totale, perché una categoria con ricavi elevati potrebbe avere margini bassi o dipendere da pochi ordini. Il numero di transazioni e il valore medio aiutano a leggere il risultato con maggiore equilibrio.
Quando i dati sono distribuiti in più tabelle, uso merge(), concettualmente simile a una join SQL.
analisi = ordini.merge(
clienti[["id_cliente", "regione"]],
on="id_cliente",
how="left",
validate="many_to_one"
)
L’opzione validate è particolarmente utile perché segnala relazioni inattese tra le tabelle. Se mi aspetto molti ordini per un cliente ma trovo duplicati nella tabella clienti, il problema non è nell’analisi finale: è nella struttura dei dati e va risolto prima.
Per le date, converto la colonna in un vero tipo temporale e posso poi estrarre mese, trimestre o giorno della settimana.
df["data"] = pd.to_datetime(df["data"])
df["mese"] = df["data"].dt.to_period("M")
vendite_mensili = (
df.groupby("mese", as_index=False)["ricavo"]
.sum()
)
Questo approccio è più affidabile del tagliare manualmente le stringhe. Le serie temporali richiedono però attenzione a fuso orario, frequenza dei dati e periodi incompleti, soprattutto quando si confrontano mesi diversi.
Come scegliere tra pandas, SQL e altri strumenti
Pandas è ottimo quando devo esplorare un dataset, costruire una trasformazione complessa o preparare dati per il machine learning. Non è sempre la scelta migliore per interrogare direttamente miliardi di righe in un database aziendale.
| Strumento | Quando lo preferisco | Limite principale |
|---|---|---|
| Pandas | Analisi esplorativa, pulizia e prototipi | Uso della memoria per dataset molto grandi |
| SQL | Filtri e aggregazioni vicino al database | Meno comodo per analisi iterative e trasformazioni specialistiche |
| Polars | Elaborazioni veloci e orientate a colonne | API e compatibilità diverse da quelle di pandas |
| Dask o Spark | Dataset distribuiti o più grandi della memoria disponibile | Maggiore complessità operativa |
La mia regola pratica è spostare nel database i filtri e le aggregazioni che possono essere eseguiti vicino alla fonte, poi usare pandas per l’analisi che richiede flessibilità. Caricare un’intera tabella quando servono solo cinque colonne e un intervallo di date è uno spreco sia di memoria sia di tempo.
Se il file è grande ma ancora gestibile, posso limitare le colonne e leggere i dati a blocchi:
for blocco in pd.read_csv(
"vendite.csv",
usecols=["data", "categoria", "ricavo"],
chunksize=100_000
):
risultato = blocco.groupby("categoria")["ricavo"].sum()
La lettura a blocchi richiede una logica di aggregazione più attenta, ma evita di caricare tutto in RAM. Quando il dataset cresce oltre la capacità del computer, invece, conviene valutare un motore progettato per il calcolo parallelo.
Gli errori più comuni nei progetti con pandas
Il primo errore è iniziare a trasformare i dati senza averne controllato la struttura. Un secondo problema frequente è usare apply() per ogni operazione, anche quando esiste una funzione vettorializzata più veloce e leggibile.
df["ricavo_netto"] = df["ricavo"] * (1 - df["sconto"])
df["anno"] = df["data"].dt.year
Queste operazioni lavorano direttamente sulle colonne e in genere sono preferibili a una funzione Python eseguita riga per riga. Non significa che apply() sia inutile, ma che dovrebbe essere una scelta motivata, non un riflesso automatico.
Un altro errore riguarda le assegnazioni su sottoinsiemi filtrati. Per rendere l’intenzione chiara uso una copia esplicita:
campione = df.loc[df["ricavo"] > 100].copy()
campione["fascia"] = "alta"
Controllo anche i tipi dopo ogni importazione importante. Numeri con virgole decimali, codici con zeri iniziali e date in formati misti possono produrre risultati apparentemente plausibili ma completamente sbagliati.
Infine, evito di costruire un unico script enorme. Separo caricamento, validazione, pulizia, trasformazione e output. Questa organizzazione rende più facile testare il processo e capire in quale passaggio nasce un errore.
Come costruire un percorso di apprendimento concreto
Per imparare pandas non partirei da tutte le funzioni della libreria. Un percorso efficace può concentrarsi prima su importazione, selezione, filtri, valori mancanti, aggregazioni e join. Sono le operazioni che ricorrono più spesso in analisi di marketing, vendite, finanza e business intelligence.
- Importare un file CSV e controllare struttura e tipi.
- Selezionare colonne e righe con condizioni leggibili.
- Gestire valori mancanti, duplicati e date.
- Creare indicatori con groupby e agg.
- Unire almeno due tabelle con merge.
- Esportare un risultato in CSV o Parquet.
Io imparerei su un dataset vicino a un problema reale, per esempio ordini e clienti di un negozio. L’obiettivo non dovrebbe essere memorizzare metodi isolati, ma produrre un piccolo report con domande verificabili, come quali categorie crescono, quali clienti acquistano di più e in quali mesi calano i ricavi.
La documentazione ufficiale di pandas resta il riferimento più sicuro per controllare parametri, tipi restituiti e comportamenti particolari. La guida introduttiva è sufficiente per partire, mentre la consultazione mirata della reference diventa importante quando il codice entra in produzione.
Il criterio che rende affidabile ogni analisi
La libreria accelera il lavoro, ma non decide se una colonna è corretta né se una media risponde davvero alla domanda aziendale. Prima di ottimizzare il codice, definisco il significato delle variabili, verifico la provenienza dei dati e confronto i risultati con un controllo indipendente.
Un buon progetto con pandas lascia traccia delle trasformazioni, mantiene separati dati originali e dati elaborati e produce risultati ripetibili. È questo, più della quantità di funzioni conosciute, che trasforma una semplice tabella in un’analisi utile per prendere decisioni.
