Created on 24 Mar 2020 ; Modified on 24 Mar 2020
In questi giorni, per analizzare alcuni andamenti dei dati della epidemia di Coronavirus COVID-19, sto utilizzando Pandas. E mi è capitato di osservare un comportamento sconcertante ...
Per chi, come me, non è un professionista nell'analisi dei dati statistici, Pandas può essere un illustre sconosciuto. Al più può ricordare per assonanza il famoso e simpatico orso, simbolo cinese, e icona del WWF.
Chi invece si occupa di analisi dei dati, sa bene che Pandas è una delle librerie di analisi dati più utilizzate. Scritta in Python, si appoggia alle librerie di calcolo algebrico NumPy e di grafica matplotlib.
Le strutture dati utilizzate sono due, relativamente semplici. La Series: una estensione dell'array monodimensionale NumPy; e il DataFrame: una estensione dell'array bidimensionale di NumPy.
Il suo utilizzo non è del tutto banale [1], ma non è neanche impossibile da utilizzare.
Bene. Lungi dal voler scrivere un tutorial sull'uso di Pandas (non sarei in grado), in questi giorni, utilizzandola mi sono imbattuto in questo comportamento.
Supponiamo di avere il seguente DataFrame di nome dfr:
col1 col2 col3 0 c11 pippo c13 1 c21 c22 c23 2 c31 pippo c33
ovvero tre righe (le righe 0, 1, e 2) e tre colonne (le colonne col1, col2, col3).
Ora, supponiamo di voler sostituire i valori pippo, presenti in due celle di col2, con il valore pluto.
Per individuare le celle, posso usare la condizione (abbastanza intuitiva): dfr['col2'] == 'pippo'. Ovvero dammi ciò che in col2 ha valore pippo. Se applico questa a dfr.loc[], ottengo le due righe che contengono pippo; ad esempo, referenziandole con dfl:
> dfl = dfr.loc[dfr['col2'] == 'pippo'] > dfl col1 col2 col3 0 c11 pippo c13 2 c31 pippo c33
e se a dfl assegno pluto, ottengo la sostituzione, ma solo in dfl, non in dfr:
> dfl['col2'] = 'pluto' > dfl col1 col2 col3 0 c11 pluto c13 2 c31 pluto c33 > dfr col1 col2 col3 0 c11 pippo c13 1 c21 c22 c23 2 c31 pippo c33
Come si vede, dfl è cambiata, e dfr no. Bene, diremo noi, che problema c'è? Significa che dfr[dfr['col2'] == 'pippo'] crea una copia dei dati. E quando effettuiamo la sostituzione l'originale non viene modificato. Mi sta bene.
Ore consideriamo quest'altro scenario:
> dfr.loc[dfr['col2'] == 'pippo', 'col2'] = 'pluto' > dfr col1 col2 col3 0 c11 pluto c13 1 c21 c22 c23 2 c31 pluto c33
ovvero, usando la stessa funzione loc, ma con due indici, il comportamento è radicalmente diverso. In questo caso la loc non mi crea una copia dell'area individuata, ma opera direttamente sull'originale.
Questa differenza di comportamento non mi è piaciuta.
[1] | Personalmente, ritengo che R sia pensata e organizzata meglio. Ma, essendo un fanatico di Python, continuo a ripetermi che le mie difficoltà con Pandas sono dovute alla scarsa dimestichezza, perché la uso raramente e con notevoli gap temporali. |