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 nanWerte 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 nanWerte 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.isnangibt ein boolesches / logisches Array zurück, das Trueüberall den Wert hat, der xkeine 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 xnur 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) == Falsenatürlich, aber ~numpy.isnan(numpy.inf) == True.
np.where(np.isfinite(x), x, 0)
xkein 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
xim Gegensatz zu Lösungen dieses Typs nur einmal angegeben werden muss x[~numpy.isnan(x)]. Dies ist praktisch, wenn dies xdurch 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)])
npPaket 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)]
xmit 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
NaNs 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 NaNund ohne infwie 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_Xenthä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 .