Ich möchte herausfinden, wie man Nanowerte aus meinem Array entfernt. Mein Array sieht ungefähr so aus:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Wie kann ich die nan
Werte entfernen x
?
Ich möchte herausfinden, wie man Nanowerte aus meinem Array entfernt. Mein Array sieht ungefähr so aus:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Wie kann ich die nan
Werte entfernen x
?
Antworten:
Wenn Sie numpy für Ihre Arrays verwenden, können Sie auch verwenden
x = x[numpy.logical_not(numpy.isnan(x))]
Gleichwertig
x = x[~numpy.isnan(x)]
[Danke an chbrown für die zusätzliche Abkürzung]
Erläuterung
Die innere Funktion numpy.isnan
gibt ein boolesches / logisches Array zurück, das True
überall den Wert hat, der x
keine Zahl ist. Da wir das Gegenteil wollen, verwenden wir den Operator logisch-nicht, ~
um True
überall ein Array mit s zu erhalten, x
das eine gültige Zahl ist.
Zuletzt verwenden wir dieses logische Array, um in das ursprüngliche Array zu indizieren und x
nur die Nicht-NaN-Werte abzurufen.
x = x[numpy.isfinite(x)]
x = x[~numpy.isnan(x)]
, was der ursprünglichen Antwort von Mutzmatron entspricht, aber kürzer ist. Wenn Sie Ihre Unendlichkeiten behalten möchten, wissen Sie das numpy.isfinite(numpy.inf) == False
natürlich, aber ~numpy.isnan(numpy.inf) == True
.
np.where(np.isfinite(x), x, 0)
x
kein Numpy-Array ist. Wenn Sie die logische Indizierung verwendet werden soll, muss es ein Array sein - zum Beispielx = np.array(x)
filter(lambda v: v==v, x)
funktioniert sowohl für Listen als auch für Numpy-Arrays, da v! = v nur für NaN ist
x
im Gegensatz zu Lösungen dieses Typs nur einmal angegeben werden muss x[~numpy.isnan(x)]
. Dies ist praktisch, wenn dies x
durch einen langen Ausdruck definiert ist und Sie den Code nicht durch Erstellen einer temporären Variablen zum Speichern des Ergebnisses dieses langen Ausdrucks überladen möchten.
Versuche dies:
import math
print [value for value in x if not math.isnan(value)]
Weitere Informationen finden Sie unter Listenverständnisse .
print ([value for value in x if not math.isnan(value)])
np
Paket verwenden: Geben Sie Ihre Liste also ohne die nans zurück:[value for value in x if not np.isnan(value)]
Für mich hat die Antwort von @jmetz nicht funktioniert, die Verwendung von pandas isnull () jedoch.
x = x[~pd.isnull(x)]
Gehen Sie wie folgt vor:
x = x[~numpy.isnan(x)]
oder
x = x[numpy.logical_not(numpy.isnan(x))]
Ich fand heraus, dass das Zurücksetzen auf dieselbe Variable (x) die tatsächlichen Nanowerte nicht entfernte und eine andere Variable verwenden musste. Wenn Sie eine andere Variable festlegen, werden die Nans entfernt. z.B
y = x[~numpy.isnan(x)]
x
mit dem neuen Wert überschreiben (dh ohne die NaNs ...). . Können Sie weitere Informationen darüber geben, warum dies passieren könnte?
Wie von anderen gezeigt
x[~numpy.isnan(x)]
funktioniert. Es wird jedoch ein Fehler ausgegeben, wenn der numpy dtype kein nativer Datentyp ist, z. B. wenn es sich um ein Objekt handelt. In diesem Fall können Sie Pandas verwenden.
x[~pandas.isna(x)] or x[~pandas.isnull(x)]
Die akzeptierte Antwort ändert ihre Form für 2D-Arrays. Ich präsentiere hier eine Lösung mit der Pandas dropna () -Funktionalität. Es funktioniert für 1D- und 2D-Arrays. Im 2D-Fall können Sie das Wetter auswählen, um die Zeile oder Spalte mit zu löschen np.nan
.
import pandas as pd
import numpy as np
def dropna(arr, *args, **kwarg):
assert isinstance(arr, np.ndarray)
dropped=pd.DataFrame(arr).dropna(*args, **kwarg).values
if arr.ndim==1:
dropped=dropped.flatten()
return dropped
x = np.array([1400, 1500, 1600, np.nan, np.nan, np.nan ,1700])
y = np.array([[1400, 1500, 1600], [np.nan, 0, np.nan] ,[1700,1800,np.nan]] )
print('='*20+' 1D Case: ' +'='*20+'\nInput:\n',x,sep='')
print('\ndropna:\n',dropna(x),sep='')
print('\n\n'+'='*20+' 2D Case: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna (rows):\n',dropna(y),sep='')
print('\ndropna (columns):\n',dropna(y,axis=1),sep='')
print('\n\n'+'='*20+' x[np.logical_not(np.isnan(x))] for 2D: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna:\n',x[np.logical_not(np.isnan(x))],sep='')
Ergebnis:
==================== 1D Case: ====================
Input:
[1400. 1500. 1600. nan nan nan 1700.]
dropna:
[1400. 1500. 1600. 1700.]
==================== 2D Case: ====================
Input:
[[1400. 1500. 1600.]
[ nan 0. nan]
[1700. 1800. nan]]
dropna (rows):
[[1400. 1500. 1600.]]
dropna (columns):
[[1500.]
[ 0.]
[1800.]]
==================== x[np.logical_not(np.isnan(x))] for 2D: ====================
Input:
[[1400. 1500. 1600.]
[ nan 0. nan]
[1700. 1800. nan]]
dropna:
[1400. 1500. 1600. 1700.]
Ein einfachster Weg ist:
numpy.nan_to_num(x)
Dokumentation: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html
NaN
s durch eine große Anzahl, während das OP darum bittet, die Elemente vollständig zu entfernen.
Dies ist mein Ansatz, um ndarray "X" nach NaNs und infs zu filtern.
Ich erstelle eine Karte von Zeilen ohne NaN
und ohne inf
wie folgt:
idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))
idx ist ein Tupel. Die zweite Spalte ( idx[1]
) enthält die Indizes des Arrays, in denen weder NaN noch inf in der Zeile gefunden wurden.
Dann:
filtered_X = X[idx[1]]
filtered_X
enthält X ohne NaN
noch inf
.
@ jmetz 'Antwort ist wahrscheinlich die, die die meisten Leute brauchen; Es ergibt sich jedoch ein eindimensionales Array, das es beispielsweise unbrauchbar macht, ganze Zeilen oder Spalten in Matrizen zu entfernen.
Dazu sollte man das logische Array auf eine Dimension reduzieren und dann das Zielarray indizieren. Im Folgenden werden beispielsweise Zeilen entfernt, die mindestens einen NaN-Wert haben:
x = x[~numpy.isnan(x).any(axis=1)]
Weitere Details finden Sie hier .