Assegnare i dati mancanti con Pandas

2 min read

Quando lavoriamo con un nuovo dataset, molte volte capita di dover gestire dei dati mancanti. In a base al tipo di dataset e alle informazioni che ne vogliamo potremmo decidere di rimuovere il record ma non sempre è la strategia migliore, perchè potremmo eliminare delle informazioni interessanti.
Di seguito vedremo come imputare sia dei valori numerici che categoriali utilizzando Pandas, una libreria in Python.

Il dataset che abbiamo scelto per questo esempio, contiene dei dati di guida, di utenti che hanno percorso il tragitto casa-lavoro e viceversa, all’interno del dataset avremo le seguenti informazioni:

  • Date: Indica la data del tragitto
  • StartTime: L’orario d’inizio del percorso
  • DayOfWeek: Il giorno della settimana
  • GoingTo: La destinazione del tragitto
  • Distance: Distanza indicata in KM
  • MaxSpeed: La massima velocità raggiunta
  • AvgSpeed: La velocità media durante il tragitto
  • AvgMovingSpeed: Velocità media registrata durante il movimento della macchina
  • FuelEconomy: Stima del consumo di carburante
  • TotalTime: Durata dell’intero percorso espresso in minuti
  • MovingTime: Tempo della macchina in movimento, al netto del traffico
  • Take407All: Se è si, ha percorso per l’intero viaggio l’autostrada 407
  • Comments: Note del guidatore

Il dataset è scaricabile dal seguente indirizzo: download dataset

Per prima cosa leggiamo i dati dal dataset e creiamo un DataFrame:

import pandas as pd
df = pd.read_csv("https://openmv.net/file/travel-times.csv")

Stampiamo le prime righe del dataset per visualizzare il tipo di dati contiene:

dataframe_head

Utilizzando la funzione shape possiamo sapere da quante righe e colonne è formato il dataset, nel nostro caso abbiamo 205 righe e 13 colonne:

df.shape
(205, 13)

In questo esempio focalizzeremo la nostra attenzione sulla colonna FuelEconomy, che riguarda i consumi del carburante, pertanto la colonna dei commenti la possiamo rimuovere attraverso il comando drop, ottenendo un DataFrame formato da 12 colonne e 205 righe:

df.drop('Comments', axis=1, inplace=True)

Siccome siamo interessati nel verificare se all’interno del dataset ci sono dei valori mancanti e cercare imputare un possibile valore corretto, utilizziamo la funzione info della libreria Pandas che restituisce il numero di record che sono valorizzati:

df.info()
dataframe_info

da come possiamo vedere dall’output ottenuto la colonna FuelEconomy ha 188 righe valorizzare quindi dobbiamo cercare d’imputare i 17 valori mancanti.

Dall’output del comando df.info() notiamo che la colonna FuelEconomy è di tipo object, quindi la prima operazione sarà la conversione in un formato numerico:

df['FuelEconomy'] = pd.to_numeric(df['FuelEconomy'], errors='coerce')

controllando nuovamente l’output di df.info() vedremo che FuelEconomy sarà di tipo float

dataframe_info_fueleconomy

Adesso dobbiamo trovare una giusta strategia per sostituire i valori mancanti con dei dati che dovrebbero essere quanto più simili alla realtà. Di seguito saranno mostrate due strategie, nella prima inseriremo il valore medio di FuelEconomy calcolato sull’intero dataset, nella seconda strategia invece terremo in considerazione se il guidatore ha percorso l’autostrada 407 in modo da prendere i valore medio dai record con le stesse caratteristiche.

Come primo passo creiamo una copia del dataframe, per non perdere le informazioni originali:

df2 = df.copy()

Proseguiamo con la prima strategia, sostituiamo i valori mancanti con il valore medio di FuelEconomy:

df2['FuelEconomy'].fillna(df2['FuelEconomy'].mean(), inplace=True)

ed eseguendo sempre il comando df2.info() vediamo che sono tutti non-null

df2_info

Applichiamo adesso la seconda strategia, creiamo due DataFrame a partire da quello originario, uno con i record di Take407All con valore “Yes” e l’altro con i valori a “No”

df_Take407 = df[df['Take407All']=='Yes']
df_NoTake407 = df[df['Take407All']=='No']

Per ciascun DataFrame creato sostituiamo i valori mancanti con il rispettivo valore medio:

df_Take407['FuelEconomy'].fillna(df_Take407['FuelEconomy'].mean(), inplace=True)

df_NoTake407['FuelEconomy'].fillna(df_NoTake407['FuelEconomy'].mean(), inplace=True)

Adesso uniamo i due DataFrame (df_Take407, df_NoTake407) in un unico DataFrame

df_merged = pd.concat([df_Take407, df_NoTake407])
df_merged.shape
(205, 12)

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *