I valori mancanti sono comuni e si verificano a causa di errore umano, errore dello strumento, elaborazione da parte di un altro team o semplicemente per mancanza di dati per una determinata osservazione.
In questo byte, daremo un'occhiata a come riempire i NaN in a
DataFrame
, se scegli di gestire i NaN riempiendoli.
Prima di tutto, creiamo un mock DataFrame
con alcuni valori casuali eliminati:
import numpy as np
array = np.random.randn(25, 3)
mask = np.random.choice([1, 0], array.shape, p=[.3, .7]).astype(bool)
array[mask] = np.nan
df = pd.DataFrame(array, columns=['Col1', 'Col2', 'Col3'])
Col1 Col2 Col3
0 -0.671603 -0.792415 0.783922
1 0.207720 NaN 0.996131
2 -0.892115 -1.282333 NaN
3 -0.315598 -2.371529 -1.959646
4 NaN NaN -0.584636
5 0.314736 -0.692732 -0.303951
6 0.355121 NaN NaN
7 NaN -1.900148 1.230828
8 -1.795468 0.490953 NaN
9 -0.678491 -0.087815 NaN
10 0.755714 0.550589 -0.702019
11 0.951908 -0.529933 0.344544
12 NaN 0.075340 -0.187669
13 NaN 0.314342 -0.936066
14 NaN 1.293355 0.098964
Tracciamo, diciamo, la terza colonna:
plt.plot(df['Col3'])
Se riempito con varie tecniche, questo grafico riempito con NaN può essere sostituito con:
fillna() – Media, mediana, moda
Puoi inserire questi valori in una nuova colonna e assegnarla alla colonna che desideri riempire o sul posto usando il inplace
discussione. Qui, estrarremo i valori riempiti in una nuova colonna per facilitare l'ispezione:
mean = df['Col3'].fillna(df['Col3'].mean(), inplace=False)
median = df['Col3'].fillna(df['Col3'].median(), inplace=False)
mode = df['Col3'].fillna(df['Col3'].mode(), inplace=False)
La mediana, la media e la moda della colonna sono -0.187669
, -0.110873
ed 0.000000
e questi valori saranno usati rispettivamente per ogni NaN. Questo sta effettivamente riempiendo con valori costanti, in cui il valore immesso dipende dall'entità della colonna.
Innanzitutto, il riempimento con i valori mediani risulta in:
Con valori medi:
Con valori di modalità:
fillna() – Valore costante
Puoi anche riempire con un valore costante invece:
Dai un'occhiata alla nostra guida pratica e pratica per l'apprendimento di Git, con le migliori pratiche, gli standard accettati dal settore e il cheat sheet incluso. Smetti di cercare su Google i comandi Git e in realtà imparare esso!
constant = df['Col3'].fillna(0, inplace=False
Ciò si traduce in un valore costante (0) inserito al posto di ogni NaN. 0
è vicino alla nostra mediana e media e uguale alla modalità, quindi i valori riempiti assomiglieranno molto a quel metodo per il nostro set di dati fittizi:
0 0.783922
1 0.996131
2 0.000000
3 -1.959646
4 -0.584636
5 -0.303951
6 0.000000
7 1.230828
8 0.000000
9 0.000000
10 -0.702019
11 0.344544
12 -0.187669
13 -0.936066
14 0.098964
fillna() – Riempimento in avanti e all'indietro
Su ogni riga: puoi eseguire un riempimento in avanti o all'indietro, prendendo il valore dalla riga prima o dopo:
ffill = df['Col3'].fillna(method='ffill')
bfill = df['Col3'].fillna(method='bfill')
Con il riempimento in avanti, poiché ci manca dalla riga 2, il valore della riga 1 viene preso per riempire la seconda. I valori si propagano in avanti:
0 0.783922
1 0.996131
2 0.996131
3 -1.959646
4 -0.584636
5 -0.303951
6 -0.303951
7 1.230828
8 1.230828
9 1.230828
10 -0.702019
11 0.344544
12 -0.187669
13 -0.936066
14 0.098964
Con il riempimento all'indietro, accade il contrario. La riga 2 viene riempita con il valore della riga 3:
0 0.783922
1 0.996131
2 -1.959646
3 -1.959646
4 -0.584636
5 -0.303951
6 1.230828
7 1.230828
8 -0.702019
9 -0.702019
10 -0.702019
11 0.344544
12 -0.187669
13 -0.936066
14 0.098964
Tuttavia, se ce n'è più di uno NaN
in sequenza: questi non funzioneranno bene e possono precipitare NaN più in basso, distorcendo i dati e rimuovendo i valori effettivamente registrati.
interpolare()
Il interpolate()
Il metodo delega l'interpolazione dei valori a SciPy suite di metodi per l'interpolazione dei valori. Accetta un'ampia varietà di argomenti, tra cui nearest
, zero
, slinear
, quadratic
, cubic
, spline
, barycentric
, polynomial
, krogh
, piecewise_polynomial
, spline
, pchip
, akima
, cubicspline
, ecc.
L'interpolazione è molto più flessibile e "intelligente" rispetto al semplice riempimento di valori con costanti o semivariabili come i metodi precedenti.
L'interpolazione può riempire correttamente una sequenza in un modo che nessun altro metodo può, come ad esempio:
s = pd.Series([0, 1, np.nan, np.nan, np.nan, 5])
s.fillna(s.mean()).values
s.fillna(method='ffill').values
s.interpolate().values
L'interpolazione predefinita è lineare e presupponendolo 1...5
è probabile un 1, 2, 3, 4, 5
la sequenza non è inverosimile (ma non è garantita). Sia il riempimento costante che il riempimento in avanti o all'indietro falliscono miseramente qui. In generale, l'interpolazione di solito è un buon amico quando si tratta di riempire NaN in segnali rumorosi o set di dati corrotti.
Sperimentare con tipi di interpolazione può produrre risultati migliori.
Ecco due metodi di interpolazione (splice
ed polynomial
richiedono un order
discussione):
nearest = df['Col3'].interpolate(method='nearest')
polynomial = df['Col3'].interpolate(method='polynomial', order=3)
Questi si traducono in:
E: