Pandas 2.0 Una rivoluzione per i Data Scientist?

Pandas 2.0 A revolution for Data Scientists?

Le Top 5 delle Caratteristiche per una Manipolazione Efficienti dei Dati

Questo aprile, pandas 2.0.0 è stato ufficialmente lanciato, creando grandi onde nella comunità della scienza dei dati. Foto di Yancy Min su Unsplash.

Grazie alla sua vasta funzionalità e versatilità, pandas ha conquistato un posto nel cuore di ogni scienziato dei dati.

Dall’input/output dei dati alla pulizia e trasformazione dei dati, è quasi impossibile pensare alla manipolazione dei dati senza import pandas as pd, giusto?

Adesso, resistete con me: con tanto chiasso intorno agli LLM negli ultimi mesi, ho in qualche modo lasciato scivolare il fatto che pandas ha appena subito un importante rilascio! Sì, pandas 2.0 è uscito e ha sparato forte!

Sebbene non fossi a conoscenza di tutto il rumore, la Comunità di AI Centric Data è intervenuta prontamente in soccorso:

La versione 2.0 sembra aver creato un grande impatto nella comunità della scienza dei dati, con molti utenti che lodano le modifiche aggiunte nella nuova versione. Screenshot dell'autore.

Curiosità: sapevate che questo rilascio è stato in preparazione per uno sbalorditivo 3 anni? Ecco quello che chiamo “impegno per la comunità”!

Allora, cosa porta pandas 2.0 sul tavolo? Scopriamolo!

1. Prestazioni, Velocità ed Efficienza della Memoria

Come tutti sappiamo, pandas è stato costruito utilizzando numpy, che non è stato progettato intenzionalmente come backend per le librerie dataframe. Per questo motivo, una delle principali limitazioni di pandas era la gestione del processing in memoria per dataset più grandi.

In questo rilascio, il grande cambiamento arriva con l’introduzione del backend di Apache Arrow per i dati di pandas.

In pratica, Arrow è un formato di dati columnar in memoria standardizzato con librerie disponibili per diversi linguaggi di programmazione (C, C++, R, Python, tra gli altri). Per Python c’è PyArrow, che si basa sull’implementazione di Arrow in C++, e quindi, rapido!

Quindi, a lungo termine, PyArrow si prende cura dei nostri precedenti vincoli di memoria delle versioni 1.X e ci consente di condurre operazioni sui dati più rapide e più efficienti in termini di memoria, specialmente per dataset più grandi.

Ecco un confronto tra la lettura dei dati senza e con il backend pyarrow, utilizzando il dataset di Hacker News, che è di circa 650 MB (Licenza CC BY-NC-SA 4.0):

Confronto tra read_csv(): Utilizzando il backend pyarrow è 35 volte più veloce. Estratto dall’autore.

Come potete vedere, utilizzando il nuovo backend, la lettura dei dati è quasi 35 volte più veloce. Altri aspetti degni di nota:

  • Senza il backend pyarrow, ogni colonna/caratteristica è memorizzata come tipo di dati unico: le caratteristiche numeriche sono memorizzate come int64 o float64, mentre i valori di stringa sono memorizzati come oggetti;
  • Con pyarrow, tutte le caratteristiche utilizzano i tipi di dati di Arrow: notare l’annotazione [pyarrow] e i diversi tipi di dati: int64, float64, string, timestamp e double:

df.info(): Investigazione dei tipi di dati di ogni DataFrame. Snippet dell’autore.

2. Tipi di dati Arrow e indici Numpy

Oltre alla lettura dei dati, che è il caso più semplice, è possibile aspettarsi ulteriori miglioramenti per una serie di altre operazioni, specialmente quelle che coinvolgono operazioni sulle stringhe, poiché l’implementazione del tipo di dati stringa di pyarrow è piuttosto efficiente:

Confronto tra operazioni sulle stringhe: dimostrazione dell’efficienza dell’implementazione di Arrow. Snippet dell’autore.

In realtà, Arrow ha più (e un supporto migliore per) tipi di dati rispetto a numpy, che sono necessari al di fuori del campo scientifico (numerico): date e orari, durata, binari, decimali, liste e mappe. Esaminare l’equivalenza tra i tipi di dati supportati da pyarrow e numpy potrebbe essere un buon esercizio nel caso vogliate imparare come sfruttarli.

È ora possibile anche utilizzare più tipi numerici numpy negli indici. I tradizionali int64, uint64 e float64 hanno aperto spazio per tutti i tipi di dati numerici di numpy, in modo tale da poter, ad esempio, specificare la loro versione a 32 bit:

Sfruttare gli indici a 32 bit di numpy, rendendo il codice più efficiente in termini di memoria. Snippet dell’autore.

Questo è un cambiamento benvenuto poiché gli indici sono una delle funzionalità più utilizzate in pandas, consentendo agli utenti di filtrare, unire e mescolare dati, tra le altre operazioni sui dati. In sostanza, più leggero è l’indice, più efficienti saranno tali processi!

3. Gestione più semplice dei valori mancanti

Il fatto che pandas sia costruito sopra a numpy ha reso difficile gestire i valori mancanti in modo facile e flessibile, poiché numpy non supporta i valori null per alcuni tipi di dati.

Ad esempio, gli interi vengono automaticamente convertiti in float, il che non è ideale:

Valori mancanti: Conversione in float. Snippet dell’autore.

Notare come points cambia automaticamente da int64 a float64 dopo l’introduzione di un singolo valore None.

Non c’è nulla di peggio per un flusso di dati che i tipi di dati errati, soprattutto all’interno di un paradigma di intelligenza artificiale centrato sui dati.

I tipi di dati errati influiscono direttamente sulle decisioni di preparazione dei dati, causano incompatibilità tra diverse porzioni di dati e, anche quando passano inosservati, possono compromettere determinate operazioni che restituiscono risultati insensati in cambio.

Come esempio, nella Community di intelligenza artificiale centrata sui dati, stiamo lavorando attualmente su un progetto di dati sintetici per la privacy dei dati. Una delle caratteristiche, NOC (numero di figli), ha dei valori mancanti e quindi viene automaticamente convertita in float quando i dati vengono caricati. Quindi, quando si passa i dati in un modello generativo come float, potremmo ottenere valori di output come decimali, come 2,5 — a meno che non siate un matematico con 2 figli, un neonato e un senso dell’umorismo strano, avere 2,5 figli non va bene.

In pandas 2.0, possiamo sfruttare dtype = 'numpy_nullable' , dove i valori mancanti sono considerati senza modificare i tipi di dati originali, in modo da mantenere i nostri tipi di dati originali (int64 in questo caso):

Sfruttare ‘numpy_nullable’, pandas 2.0 può gestire i valori mancanti senza modificare i tipi di dati originali. Snippet dell’autore.

Potrebbe sembrare un cambiamento sottile, ma sotto il cofano significa che ora pandas può utilizzare nativamente l’implementazione di Arrow per gestire i valori mancanti. Ciò rende le operazioni molto più efficienti, poiché pandas non deve implementare la propria versione per gestire i valori null per ogni tipo di dati.

4. Ottimizzazione della copia su scrittura

Pandas 2.0 introduce anche un nuovo meccanismo di copia ritardata che differisce la copia degli oggetti DataFrame e Series fino a quando non vengono modificati.

Ciò significa che determinati metodi restituiranno viste anziché copie quando la copia su scrittura è abilitata, migliorando l’efficienza della memoria minimizzando la duplicazione non necessaria dei dati.

Significa anche che devi fare molta attenzione quando usi assegnamenti concatenati.

Se la modalità di copia su scrittura è abilitata, gli assegnamenti concatenati non funzioneranno perché puntano a un oggetto temporaneo che è il risultato di un’operazione di indicizzazione (che in copia su scrittura si comporta come una copia).

Quando copy_on_write è disabilitato, le operazioni come la suddivisione possono modificare l’originale df se il nuovo dataframe viene cambiato:

Copia su Scrittura Disabilitata: il dataframe originale viene modificato negli assegnamenti concatenati. Estratto dall’autore.

Quando copy_on_write è abilitato, viene creata una copia all’assegnazione e quindi l’originale dataframe non viene mai modificato. Pandas 2.0 genererà un ChainedAssignmentError in queste situazioni per evitare bug silenziosi:

Copia su Scrittura Abilitata: il dataframe originale non viene modificato negli assegnamenti concatenati. Estratto dall’autore.

5. Dipendenze Opzionali

Utilizzando pip, la versione 2.0 ci dà la flessibilità di installare le dipendenze opzionali, il che è un plus in termini di personalizzazione e ottimizzazione delle risorse.

Possiamo adattare l’installazione alle nostre esigenze specifiche, senza spendere spazio su disco per ciò che non ci serve veramente.

Inoltre, risparmia molta “preoccupazione per le dipendenze”, riducendo la probabilità di problemi di compatibilità o conflitti con altri pacchetti che potremmo avere nei nostri ambienti di sviluppo:

Installazione di Dipendenze Opzionali. Estratto dall’autore.

Proviamolo!

Tuttavia, la domanda rimane: la popolarità è davvero giustificata? Ero curioso di vedere se pandas 2.0 offriva miglioramenti significativi rispetto ad alcuni pacchetti che uso ogni giorno: ydata-profiling, matplotlib, seaborn, scikit-learn.

Di questi, ho deciso di provare ydata-profiling per vedere come funziona – ha appena aggiunto il supporto per pandas 2.0, che sembrava essere un must-have per la comunità! Nella nuova versione, gli utenti possono stare tranquilli che le loro pipeline non si romperanno se stanno usando pandas 2.0, e questo è un grande vantaggio! Ma cos’altro?

A dire il vero, ydata-profiling è stato uno dei miei strumenti preferiti per l’analisi dei dati esplorativi, ed è anche un bel benchmark veloce – una riga di codice da parte mia, ma sotto il cofano è pieno di calcoli che come scienziato dei dati devo elaborare – statistiche descrittive, plotting degli istogrammi, analisi delle correlazioni, e così via.

Quale modo migliore per testare l’impatto del motore pyarrow su tutti questi contemporaneamente con uno sforzo minimo?

Benchmarking con ydata-profiling. Estratto dall’autore.

Di nuovo, la lettura dei dati è sicuramente migliore con il motore pyarrow, anche se la creazione del profilo dei dati non è cambiata significativamente in termini di velocità.

Tuttavia, le differenze potrebbero dipendere dall’efficienza della memoria, per la quale dovremmo eseguire un’analisi diversa. Inoltre, potremmo approfondire il tipo di analisi condotte sui dati: per alcune operazioni, la differenza tra le versioni 1.5.2 e 2.0 sembra trascurabile.

Ma la cosa principale che ho notato che potrebbe fare la differenza a questo riguardo è che ydata-profiling non sfrutta ancora i tipi di dati di pyarrow. Questo aggiornamento potrebbe avere un grande impatto sia sulla velocità che sulla memoria ed è qualcosa che attendo con impazienza in futuro!

Il Verdetto: Prestazioni, Flessibilità, Interoperabilità!

Questa nuova versione di pandas 2.0 porta molta flessibilità e ottimizzazione delle prestazioni con modifiche “sotto il cofano” sottili ma cruciali.

Forse non sono “sgargianti” per i nuovi arrivati nel campo della manipolazione dei dati, ma sicuramente sono come acqua nel deserto per i veterani scienziati dei dati che dovevano saltare attraverso gli ostacoli per superare le limitazioni delle versioni precedenti.

Per riassumere, questi sono i principali vantaggi introdotti nella nuova versione:

  • Ottimizzazione delle prestazioni: Con l’introduzione del backend di Apache Arrow, più indici numpy dtype e la modalità copy-on-write;
  • Maggiore flessibilità e personalizzazione: Consente agli utenti di controllare le dipendenze opzionali e di sfruttare i tipi di dati di Apache Arrow (compresa la nullabilità fin dall’inizio!);
  • Interoperabilità: Forse un vantaggio meno “acclamato” della nuova versione ma con un enorme impatto. Poiché Arrow è indipendente dal linguaggio, i dati in memoria possono essere trasferiti tra programmi costruiti non solo su Python, ma anche su R, Spark e altri che utilizzano il backend di Apache Arrow!

Ecco fatto, amici! Spero che questo riassunto abbia risposto a qualche tua domanda su pandas 2.0 e la sua applicabilità alle nostre attività di manipolazione dei dati.

Sono ancora curioso se hai trovato differenze significative nella tua programmazione quotidiana con l’introduzione di pandas 2.0! Se ne hai voglia, vieni a trovarmi nella community Data-Centric AI e fammi sapere cosa ne pensi! Ci vediamo lì?

A proposito di me

Dottore di ricerca, ricercatore di Machine Learning, educatore, difensore dei dati e “uomo tuttofare” in generale. Qui su Nisoo, scrivo su Data-Centric AI e Data Quality, educando le comunità di Data Science e Machine Learning su come passare da dati imperfetti a dati intelligenti.

Relazioni con gli sviluppatori @ YData | Community Data-Centric AI | GitHub | Instagram | Google Scholar | LinkedIn