Pandas è stata la libreria Python predefinita per l’analisi dati per oltre un decennio. Nel 2026 è ancora ovunque — ma non è più la scelta ovvia. Una nuova generazione di librerie offre prestazioni drasticamente migliori, minor consumo di memoria e API più intuitive.

Questa guida confronta le principali opzioni e aiuta a determinare quale si adatta meglio ai diversi casi d’uso.

I contendenti

LibreriaMaturitàScritta inVantaggio principale
Pandas 2.2MaturaC/PythonEcosistema, familiarità
Polars 1.xStabileRustVelocità, efficienza di memoria
DuckDB 1.xStabileC++Interfaccia SQL, zero-copy
ModinStabilePythonSostituzione drop-in di Pandas
VaexManutenzioneC++/PythonElaborazione out-of-core
DataFusion (Python)In crescitaRustNativo Apache Arrow

Prestazioni: Cosa mostrano i benchmark

Invece di inventare numeri, ecco cosa dimostrano i benchmark ufficiali e di terze parti:

Benchmark Polars PDS-H (derivato da TPC-H)

Il team Polars mantiene una suite di benchmark open source derivata dal benchmark decisionale TPC-H, chiamata PDS-H. I risultati più recenti (maggio 2025) confrontano Polars con Pandas e altri motori su query analitiche standardizzate.

Risultati chiave dal benchmark ufficiale:

  • Polars supera costantemente Pandas con un margine significativo su tutte le 22 query derivate da TPC-H
  • Polars utilizza sostanzialmente meno memoria rispetto a Pandas per operazioni equivalenti
  • Il benchmark è open source su GitHub, quindi i risultati sono riproducibili

Studio su energia e prestazioni

Uno studio separato sui benchmark energetici di Polars ha rilevato che Polars ha consumato circa 8× meno energia rispetto a Pandas in compiti sintetici di analisi dati con DataFrame di grandi dimensioni, e ha utilizzato circa il 63% dell’energia richiesta da Pandas per query di tipo TPC-H su dataset di grandi dimensioni.

Caratteristiche prestazionali generali

Sulla base dei benchmark pubblicati e dei report della community:

  • Polars e DuckDB sono significativamente più veloci di Pandas per la maggior parte delle operazioni analitiche, particolarmente su dataset superiori a 1M di righe
  • DuckDB tende ad essere particolarmente forte su carichi di lavoro pesanti in aggregazione e join
  • Modin offre accelerazioni moderate rispetto a Pandas, ma al costo di un maggiore consumo di memoria
  • Pandas 2.x con dtypes basati su Arrow è sensibilmente più veloce di Pandas 1.x

Nota: I rapporti prestazionali esatti dipendono fortemente da hardware, forma dei dati e complessità delle query. Eseguite sempre i benchmark sui vostri carichi di lavoro.


Polars — Il nuovo standard per il lavoro critico in termini di prestazioni

Per i nuovi progetti dove le prestazioni contano, Polars si è affermato come l’alternativa di riferimento a Pandas.

import polars as pl

df = pl.read_parquet("events.parquet")

result = (
    df.lazy()
    .filter(pl.col("event_type") == "purchase")
    .group_by("user_id")
    .agg([
        pl.col("amount").sum().alias("total_spent"),
        pl.col("amount").count().alias("num_purchases"),
    ])
    .sort("total_spent", descending=True)
    .head(100)
    .collect()
)

Perché Polars spicca:

  • Significativamente più veloce di Pandas nella maggior parte delle operazioni — confermato dai benchmark ufficiali PDS-H (fonte)
  • Lazy evaluation che ottimizza il piano di query prima dell’esecuzione. Scrivere .lazy() all’inizio e .collect() alla fine è la singola ottimizzazione prestazionale più importante disponibile
  • API coerente che evita le molte insidie di Pandas (SettingWithCopyWarning, vi dice qualcosa?)
  • Basato su Rust con parallelismo reale — utilizza tutti i core disponibili di default

Gli svantaggi onesti:

  • Gap nell’ecosistema: molte librerie si aspettano ancora DataFrame Pandas. La conversione con .to_pandas() è talvolta inevitabile
  • L’integrazione con il plotting è più debole — Matplotlib/Seaborn si aspettano input Pandas
  • L’API è sufficientemente diversa da presentare una vera curva di apprendimento. I team esperti di Pandas dovrebbero prevedere circa una settimana per la transizione

DuckDB — Quando SQL è l’interfaccia preferita

DuckDB non è una libreria DataFrame — è un database analitico embedded. Ma è diventato uno dei modi migliori per analizzare dati in Python.

import duckdb

result = duckdb.sql("""
    SELECT 
        user_id,
        SUM(amount) as total_spent,
        COUNT(*) as num_purchases
    FROM read_parquet('events.parquet')
    WHERE event_type = 'purchase'
    GROUP BY user_id
    ORDER BY total_spent DESC
    LIMIT 100
""").fetchdf()

Perché DuckDB è convincente:

  • Eccellenti prestazioni di aggregazione — competitivo o più veloce di Polars su operazioni groupby e join
  • Integrazione zero-copy con Pandas, Polars e Arrow. Le query SQL possono referenziare DataFrame Pandas senza copiare dati
  • Legge Parquet, CSV, JSON direttamente — nessun passaggio di caricamento esplicito necessario
  • Embedded — nessun server, nessuna configurazione, solo pip install duckdb

Quando scegliere DuckDB rispetto a Polars:

  • Il team è più a suo agio con SQL che con il method chaining
  • Interrogare file direttamente senza costruire una pipeline
  • Unire dati da formati diversi (CSV + Parquet + JSON)

Quando Polars è la scelta migliore:

  • Trasformazioni complesse a più passaggi (il method chaining tende a essere più leggibile dell’SQL annidato)
  • Costruire pipeline dati in codice Python
  • Quando serve un controllo granulare sull’esecuzione

Pandas 2.2 — Ancora rilevante (con riserve)

Pandas non è morto. Con i dtypes basati su Arrow nella versione 2.x, è significativamente più veloce di Pandas 1.x:

import pandas as pd

# Usare dtypes Arrow per prestazioni migliori
df = pd.read_parquet("events.parquet", dtype_backend="pyarrow")

Scegliere ancora Pandas quando:

  • Il team lo conosce già bene e le prestazioni sono adeguate
  • Serve massima compatibilità con le librerie (scikit-learn, statsmodels, ecc.)
  • Si lavora con dataset piccoli (<1M righe) dove le differenze prestazionali sono trascurabili
  • Si fa analisi esplorativa nei notebook Jupyter

Considerare alternative quando:

  • I dataset superano la RAM disponibile
  • Si costruiscono pipeline dati di produzione dove le prestazioni contano
  • Si lavora regolarmente con dataset superiori a 10M righe

Modin — Una raccomandazione difficile

Modin promette di accelerare Pandas cambiando una sola riga di import. In pratica, i compromessi sono significativi:

  • Maggiore consumo di memoria rispetto a Pandas stesso (distribuisce i dati tra i processi)
  • Copertura API incompleta — alcune operazioni ricadono silenziosamente su Pandas
  • Overhead di avvio che lo rende più lento per dataset piccoli
  • Complessità di debug che aumenta quando l’esecuzione distribuita incontra problemi

Valutazione: Per la maggior parte dei team, è meglio restare con Pandas (per la compatibilità) o passare a Polars (per le prestazioni). Modin occupa una posizione intermedia scomoda che non soddisfa pienamente nessuno dei due obiettivi.


Il framework decisionale

I dati sono < 1M righe?
  → Pandas (con dtypes Arrow) va benissimo. Non complicatevi la vita.

Il team preferisce SQL?
  → DuckDB.

Si sta costruendo una pipeline dati Python?
  → Polars.

Serve interrogare file senza caricarli?
  → DuckDB.

Dati > 100M righe su una singola macchina?
  → Polars (lazy mode) o DuckDB.

Dati più grandi della RAM disponibile?
  → DuckDB o Polars (modalità streaming).

Approfondimenti

Domande sulla migrazione da Pandas? Contattateci a [email protected].