Fehlende Werte sind häufig und treten entweder aufgrund menschlicher Fehler, Instrumentenfehler, Verarbeitung durch ein anderes Team oder anderweitig einfach aufgrund eines Mangels an Daten für eine bestimmte Beobachtung auf.
In diesem Byte werfen wir einen Blick darauf, wie NaNs in a gefüllt werden
DataFrame
, wenn Sie sich dafür entscheiden, NaNs durch Ausfüllen zu handhaben.
Lassen Sie uns zunächst einen Mock erstellen DataFrame
mit einigen zufälligen Werten ausgefallen:
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
Lassen Sie uns, sagen wir, die dritte Spalte plotten:
plt.plot(df['Col3'])
Wenn es mit verschiedenen Techniken gefüllt ist, kann dieses mit NaN gefüllte Diagramm ersetzt werden durch:
fillna() – Mittelwert, Median, Modus
Sie können diese Werte in eine neue Spalte eingeben und sie der Spalte zuweisen, die Sie füllen möchten, oder an Ort und Stelle mit verwenden inplace
Streit. Hier extrahieren wir die gefüllten Werte in einer neuen Spalte zur leichteren Überprüfung:
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)
Median, Mittelwert und Modus der Spalte sind -0.187669
, -0.110873
und 0.000000
und diese Werte werden jeweils für jedes NaN verwendet. Dies ist effektiv das Füllen mit konstanten Werten, wobei der eingegebene Wert vom Eintrag der Spalte abhängt.
Zunächst ergibt das Auffüllen mit Medianwerten:
Mit Mittelwerten:
Mit Moduswerten:
fillna() – Konstanter Wert
Sie können stattdessen auch mit einem konstanten Wert füllen:
Sehen Sie sich unseren praxisnahen, praktischen Leitfaden zum Erlernen von Git an, mit Best Practices, branchenweit akzeptierten Standards und einem mitgelieferten Spickzettel. Hören Sie auf, Git-Befehle zu googeln und tatsächlich in Verbindung, um es!
constant = df['Col3'].fillna(0, inplace=False
Dies führt dazu, dass anstelle jedes NaN ein konstanter Wert (0) gesetzt wird. 0
ist nahe an unserem Median und Mittelwert und gleich dem Modus, sodass die gefüllten Werte dieser Methode für unseren Scheindatensatz sehr ähnlich sind:
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() – Vorwärts- und Rückwärtsfüllung
In jeder Zeile – Sie können eine Vorwärts- oder Rückwärtsfüllung durchführen, indem Sie den Wert entweder aus der Zeile davor oder danach nehmen:
ffill = df['Col3'].fillna(method='ffill')
bfill = df['Col3'].fillna(method='bfill')
Da wir beim Vorwärtsfüllen in Zeile 2 fehlen, wird der Wert aus Zeile 1 verwendet, um die zweite Zeile zu füllen. Die Werte propagieren vorwärts:
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
Beim Rückwärtsfüllen passiert das Gegenteil. Zeile 2 wird mit dem Wert aus Zeile 3 gefüllt:
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
Allerdings, wenn es mehr als eine gibt NaN
in einer Sequenz – diese funktionieren nicht gut und können NaNs weiter nach unten kaskadieren, die Daten verzerren und tatsächlich aufgezeichnete Werte entfernen.
interpolieren()
Das interpolate()
-Methode delegiert die Interpolation von Werten an SciPy Suite von Methoden zum Interpolieren von Werten. Es akzeptiert eine Vielzahl von Argumenten, einschließlich nearest
, zero
, slinear
, quadratic
, cubic
, spline
, barycentric
, polynomial
, krogh
, piecewise_polynomial
, spline
, pchip
, akima
, cubicspline
, usw.
Die Interpolation ist viel flexibler und „intelligenter“, als nur Werte mit Konstanten oder Halbvariablen wie bei früheren Methoden zu füllen.
Die Interpolation kann eine Sequenz auf eine Weise richtig füllen, wie es keine anderen Methoden können, wie zum Beispiel:
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
Die Standardinterpolation ist linear, und davon ausgegangen 1...5
ist wahrscheinlich a 1, 2, 3, 4, 5
Reihenfolge ist nicht weit hergeholt (aber nicht garantiert). Sowohl Dauerbefüllung als auch Vorwärts- oder Rückwärtsbefüllung scheitern hier kläglich. Allgemein gesagt – Interpolation wird normalerweise ein guter Freund sein, wenn es darum geht, NaNs in verrauschte Signale oder beschädigte Datensätze zu füllen.
Das Experimentieren mit Interpolationsarten kann zu besseren Ergebnissen führen.
Hier sind zwei Interpolationsmethoden (splice
und polynomial
erfordern eine order
Streit):
nearest = df['Col3'].interpolate(method='nearest')
polynomial = df['Col3'].interpolate(method='polynomial', order=3)
Diese ergeben:
Und: