0Pricing
Pandas & NumPy Academy · Lezione

Riempire i valori mancanti

Sostituisca NaN con una costante, la media della colonna, il riempimento in avanti o all'indietro usando fillna() e il relativo parametro method.

Riempire i valori mancanti è una lezione Pandas & NumPy Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Pandas & NumPy Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Pandas & NumPy Academy include 4 lezioni in totale.

Introduzione a fillna()

L'imputazione consiste nel sostituire i valori mancanti con un valore sostitutivo ragionevole invece di eliminare la riga. Pandas fillna() è lo strumento principale per questa operazione: sostituisce ogni NaN in una Series o in un DataFrame con un valore specificato. A differenza dell'eliminazione, l'imputazione preserva tutte le righe, un aspetto particolarmente importante quando i dati sono scarsi o quando il modello dei dati mancanti contiene informazioni.

La forma più semplice passa uno scalare: df['col'].fillna(0).

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'product': ['A', 'B', 'C', 'D'],
    'price': [10.0, np.nan, 30.0, np.nan]
})

# Fill all NaN in 'price' with 0
filled = df['price'].fillna(0)
print(filled)
# 0    10.0
# 1     0.0
# 2    30.0
# 3     0.0

Riempimento con la media o la mediana di una colonna

Riempire con la media della colonna (per distribuzioni simmetriche) o con la mediana (per distribuzioni asimmetriche) è una delle strategie di imputazione più comuni. Queste statistiche rappresentano la tendenza centrale dei dati, quindi minimizzano la distorsione della distribuzione della colonna. Calcoli sempre la statistica sulla suddivisione di addestramento per evitare la fuga di dati.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'salary': [50000, np.nan, 70000, 80000, np.nan, 60000]
})

mean_salary = df['salary'].mean()
median_salary = df['salary'].median()

df['salary_mean_filled'] = df['salary'].fillna(mean_salary)
df['salary_median_filled'] = df['salary'].fillna(median_salary)
print(df)
#     salary  salary_mean_filled  salary_median_filled
# 0  50000.0             50000.0               50000.0
# 1      NaN             65000.0               65000.0
# 2  70000.0             70000.0               70000.0

Riempimento delle variabili categoriche con la moda

Per le colonne categoriche, riempire con la media o la mediana non è sensato. Utilizzi invece la moda, cioè il valore che compare più frequentemente. Series.mode()[0] restituisce il valore più comune (il valore [0] gestisce il caso in cui esistano più mode).

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'status': ['active', 'inactive', None, 'active', None, 'active']
})

most_common = df['status'].mode()[0]
print('Mode:', most_common)  # active

df['status'] = df['status'].fillna(most_common)
print(df['status'].tolist())
# ['active', 'inactive', 'active', 'active', 'active', 'active']

Riempimento in avanti con ffill()

Il riempimento in avanti (detto anche last-observation-carried-forward, LOCF) propaga in avanti l'ultimo valore valido (non NaN) per riempire le posizioni NaN successive. È ideale per i dati di serie temporali in cui una misurazione rimane costante fino al suo aggiornamento, ad esempio lo stato di un dispositivo, i livelli dei prezzi o le letture di un sensore che cambiano solo in corrispondenza di eventi specifici.

import pandas as pd
import numpy as np

price = pd.Series(
    [100, np.nan, np.nan, 105, np.nan, 110],
    index=pd.date_range('2024-01', periods=6, freq='ME')
)

filled = price.ffill()
print(filled)
# 2024-01-31    100.0
# 2024-02-29    100.0
# 2024-03-31    100.0
# 2024-04-30    105.0
# 2024-05-31    105.0
# 2024-06-30    110.0

Riempimento all'indietro con bfill()

Il riempimento all'indietro (next-observation-carried-backward, NOCB) propaga all'indietro il valore valido successivo per riempire le posizioni NaN precedenti. È utile quando si sa che i dati futuri completano i valori mancanti del passato, ad esempio quando si ricevono i dati di fine mese e si devono completare a ritroso i giorni precedenti all'arrivo del report.

import pandas as pd
import numpy as np

df = pd.DataFrame({'value': [np.nan, np.nan, 3, np.nan, 5]})

print(df['value'].bfill())
# 0    3.0
# 1    3.0
# 2    3.0
# 3    5.0
# 4    5.0
# dtype: float64

Parametro limit per il riempimento in avanti e all'indietro

Sia ffill() sia bfill() accettano un parametro limit che limita il numero di valori NaN consecutivi da riempire. Questo è importante quando si desidera propagare un valore in avanti solo per un breve intervallo: gli intervalli lunghi dovrebbero rimanere NaN per indicare che i dati sono effettivamente mancanti e non semplicemente in ritardo.

import pandas as pd
import numpy as np

s = pd.Series([1.0, np.nan, np.nan, np.nan, 5.0])

# Fill only the first NaN gap, leave the rest
print(s.ffill(limit=1))
# 0    1.0
# 1    1.0   <- filled
# 2    NaN   <- still NaN (limit reached)
# 3    NaN
# 4    5.0

Riempimento differenziato delle colonne

In un DataFrame reale, colonne diverse possono richiedere strategie di riempimento diverse. Passi un dizionario a fillna(), in cui le chiavi sono i nomi delle colonne e i valori sono i valori da utilizzare per il riempimento. In questo modo applica un'imputazione specifica per colonna in una sola chiamata, una soluzione più ordinata rispetto al concatenamento di più chiamate individuali a fillna.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'age': [25, np.nan, 30],
    'income': [50000, np.nan, 70000],
    'country': ['USA', np.nan, 'UK']
})

fill_values = {
    'age': df['age'].median(),
    'income': df['income'].mean(),
    'country': 'Unknown'
}

filled = df.fillna(fill_values)
print(filled)
#     age   income  country
# 0  25.0  50000.0      USA
# 1  27.5  60000.0  Unknown
# 2  30.0  70000.0       UK

Imputazione basata sui gruppi

Una strategia più sofisticata consiste nel riempire i valori NaN con la media o la mediana del gruppo invece che con la media complessiva della colonna. Ad esempio, può riempire uno stipendio mancante con lo stipendio mediano della relativa categoria professionale. Questo preserva la struttura dei sottogruppi e produce imputazioni più realistiche rispetto a una statistica globale.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'dept': ['Eng', 'Eng', 'HR', 'HR', 'Eng'],
    'salary': [90000, np.nan, 50000, np.nan, 110000]
})

# Fill salary NaN with the median salary for each department
df['salary'] = df.groupby('dept')['salary'].transform(
    lambda x: x.fillna(x.median())
)
print(df)
#    dept   salary
# 0   Eng  90000.0
# 1   Eng  100000.0   <- group median (90k+110k)/2
# 2    HR  50000.0
# 3    HR  50000.0
# 4   Eng  110000.0

Riempimento con un valore sentinella costante

A volte l'imputazione corretta consiste in un valore sentinella che segnala «sconosciuto» invece di rappresentare una misurazione reale. Ad esempio, -1 per un'età sconosciuta, «N/A» per una categoria sconosciuta oppure False per un flag booleano sconosciuto. I valori sentinella sono validi quando il codice a valle li controlla esplicitamente e li tratta in modo diverso dai dati reali.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'user_id': [1, 2, 3],
    'referral_source': ['email', np.nan, 'ad'],
    'trial_days': [14, np.nan, 7]
})

df['referral_source'] = df['referral_source'].fillna('unknown')
df['trial_days'] = df['trial_days'].fillna(-1).astype(int)
print(df)
#    user_id referral_source  trial_days
# 0        1           email          14
# 1        2         unknown          -1
# 2        3              ad           7

Concatenamento di fillna() in una pipeline

Come tutti i metodi Pandas, fillna() restituisce un nuovo DataFrame e si integra perfettamente in una catena di metodi. Chiamare .fillna() dopo .dropna() applica una strategia in due passaggi: elimina le righe prive di colonne fondamentali, quindi riempie i valori NaN opzionali rimanenti con valori predefiniti sensati, il tutto in una pipeline leggibile.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'user_id': [1, None, 3, 4],
    'score': [88, 95, np.nan, 76],
    'label': ['A', 'B', None, 'D']
})

cleaned = (
    df
    .dropna(subset=['user_id'])
    .fillna({'score': df['score'].mean(), 'label': 'Unknown'})
)
print(cleaned)
#    user_id  score    label
# 0      1.0   88.0        A
# 2      3.0   86.3  Unknown
# 3      4.0   76.0        D

Verifica dell'assenza di NaN residui

Dopo l'imputazione, verifichi sempre che non rimangano valori NaN nelle colonne interessate. Chiami df.isna().sum() oppure verifichi con un'asserzione che il conteggio sia zero. Un conteggio diverso da zero indica che fillna non ha gestito un caso: ad esempio, una colonna potrebbe avere un dtype che ha impedito il riempimento oppure potrebbe mancare una colonna nel dizionario.

import pandas as pd
import numpy as np

df = pd.DataFrame({'a': [1.0, np.nan, 3.0], 'b': [np.nan, 2.0, 3.0]})
filled = df.fillna(0)

# Verify
assert filled.isna().sum().sum() == 0, 'Some NaN remain!'
print('All NaN filled successfully')
print(filled.isna().sum())
# a    0
# b    0
# dtype: int64

Verifica rapida

Verifichi la Sua comprensione del riempimento dei valori mancanti in Pandas.

Riepilogo della lezione

In questa lezione ha imparato che: fillna(scalar) sostituisce tutti i NaN con una costante, fillna(mean/median) esegue l'imputazione utilizzando le statistiche della colonna e ffill()/bfill() propagano i valori adiacenti nelle serie temporali. Passi un dizionario a fillna() per applicare strategie specifiche alle colonne e utilizzi groupby().transform() per un'imputazione basata sui gruppi. Ora vedremo l'interpolazione e quando scegliere tecniche di imputazione avanzate.

Domande Frequenti

La lezione «Riempire i valori mancanti» è gratuita?

Sì — il testo completo di «Riempire i valori mancanti» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Pandas & NumPy Academy, passa a CoddyKit PRO. Il corso Pandas & NumPy Academy include 4 lezioni in totale.

Cosa imparerò in «Riempire i valori mancanti»?

Sostituisca NaN con una costante, la media della colonna, il riempimento in avanti o all'indietro usando fillna() e il relativo parametro method. Eserciti Pandas & NumPy Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Pandas & NumPy Academy?

Non è richiesta alcuna esperienza precedente. Pandas & NumPy Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Riempire i valori mancanti»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Pandas & NumPy Academy?

Sì. Ogni lezione Pandas & NumPy Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Rilevare i valori mancanti
  2. Eliminare i valori mancanti
  3. Riempire i valori mancanti
  4. Interpolazione e imputazione avanzata
← Torna a Pandas & NumPy Academy