Ich möchte herausfinden, wie man nan-Werte aus meinem Array entfernt. Es sieht ungefähr so aus:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Ich bin relativ neu in Python, also lerne ich immer noch. Irgendwelche Tipps?
Wenn Sie für Ihre Arrays Numpy 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 hinzugefügte Kurzschrift]
Erklärung
Die innere Funktion numpy.isnan
gibt ein boolesches/logisches Array zurück, das überall den Wert True
hat, an dem x
keine Zahl ist. Da wir das Gegenteil wollen, verwenden wir den logisch-nicht-Operator ~
, um ein Array mit True
s überall dort zu erhalten, dass x
is eine gültige Zahl ist.
Zuletzt verwenden wir dieses logische Array, um in das ursprüngliche Array x
zu indexieren, um nur die Nicht-NaN-Werte abzurufen.
filter(lambda v: v==v, x)
funktioniert sowohl für Listen als auch für numpy array , da v! = v nur für NaN
Versuche dies:
import math
print [value for value in x if not math.isnan(value)]
Weitere Informationen finden Sie unter List Comprehensions .
Für mich hat die Antwort von @jmetz nicht funktioniert, allerdings hat pandas isnull () verwendet.
x = x[~pd.isnull(x)]
Die oben genannten tun:
x = x[~numpy.isnan(x)]
oder
x = x[numpy.logical_not(numpy.isnan(x))]
Ich stellte fest, dass das Zurücksetzen auf dieselbe Variable (x) die tatsächlichen nan-Werte nicht löste und eine andere Variable verwendet werden musste. Durch das Einstellen auf eine andere Variable wurden die Nans entfernt.
y = x[~numpy.isnan(x)]
Wie von anderen gezeigt
x[~numpy.isnan(x)]
funktioniert. Es wird jedoch ein Fehler ausgegeben, wenn der numpy-Datentyp kein nativer Datentyp ist, beispielsweise wenn es sich um ein Objekt handelt. In diesem Fall können Sie Pandas verwenden.
x[~pandas.isnan(x)]
Wenn Sie numpy
verwenden
# first get the indices where the values are finite
ii = np.isfinite(x)
# second get the values
x = x[ii]
Die akzeptierte Antwort ändert die 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 Wetter wählen, um die Zeile oder Spalte zu löschen mit 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.]
Dies ist mein Ansatz für das Filtern von ndarray "X" für NaNs und Infs.
Ich erstelle eine Zuordnung von Zeilen ohne NaN
und inf
wie folgt:
idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))
idx ist ein Tupel. Ihre zweite Spalte (idx[1]
) enthält die Indizes des Arrays, wobei in der Zeile weder NaN noch inf gefunden wurden.
Dann:
filtered_X = X[idx[1]]
filtered_X
enthält X ohne NaN
oder inf
.