Chcę dowiedzieć się, jak usunąć wartości nan z mojej tablicy. Moja tablica wygląda mniej więcej tak:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Jak mogę usunąć nan
wartości x
?
Chcę dowiedzieć się, jak usunąć wartości nan z mojej tablicy. Moja tablica wygląda mniej więcej tak:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Jak mogę usunąć nan
wartości x
?
Odpowiedzi:
Jeśli używasz numpy do swoich tablic, możesz także użyć
x = x[numpy.logical_not(numpy.isnan(x))]
Równoważnie
x = x[~numpy.isnan(x)]
[Podziękowania dla chbrown za dodanie stenografii]
Wyjaśnienie
Funkcja wewnętrzna numpy.isnan
zwraca tablicę logiczną / logiczną, która ma wartość True
wszędzie, gdzie x
nie jest liczbą. W przeciwieństwie do tego, używamy logicznego operatora, ~
aby uzyskać tablicę True
zs wszędzie, gdzie x
jest poprawna liczba.
Na koniec używamy tej tablicy logicznej do indeksowania do oryginalnej tablicy x
, aby pobrać tylko wartości inne niż NaN.
x = x[numpy.isfinite(x)]
x = x[~numpy.isnan(x)]
, co odpowiada oryginalnej odpowiedzi mutzmatronu, ale jest krótsze. Jeśli chcesz zachować swoje nieskończoności, wiedz o tym numpy.isfinite(numpy.inf) == False
oczywiście, ale ~numpy.isnan(numpy.inf) == True
.
np.where(np.isfinite(x), x, 0)
x
nie są tablicami liczbowymi. Jeśli chcesz użyć indeksowania logicznego, musi to być tablica - np.x = np.array(x)
filter(lambda v: v==v, x)
działa zarówno dla list, jak i tablicy numpy, ponieważ v! = v tylko dla NaN
x
go podać tylko raz, w przeciwieństwie do rozwiązań tego typu x[~numpy.isnan(x)]
. Jest to wygodne, gdy x
jest zdefiniowane długim wyrażeniem i nie chcesz zaśmiecać kodu, tworząc tymczasową zmienną do przechowywania wyniku tego długiego wyrażenia.
Spróbuj tego:
import math
print [value for value in x if not math.isnan(value)]
Aby uzyskać więcej informacji, zapoznaj się z listami .
print ([value for value in x if not math.isnan(value)])
np
pakiecie: Więc zwraca listę bez nans:[value for value in x if not np.isnan(value)]
Dla mnie odpowiedź @jmetz nie działała, jednak użycie pandas isnull () działało.
x = x[~pd.isnull(x)]
Wykonując powyższe:
x = x[~numpy.isnan(x)]
lub
x = x[numpy.logical_not(numpy.isnan(x))]
Odkryłem, że zresetowanie do tej samej zmiennej (x) nie usunęło rzeczywistych wartości nan i musiałem użyć innej zmiennej. Ustawienie innej zmiennej usunęło nans. na przykład
y = x[~numpy.isnan(x)]
x
nadpisywać nową wartością (tj. bez NaNs ...) . Czy możesz podać więcej informacji, dlaczego tak się dzieje?
Jak pokazują inni
x[~numpy.isnan(x)]
Pracuje. Ale wyrzuci błąd, jeśli typ numpy nie jest rodzimym typem danych, na przykład jeśli jest obiektem. W takim przypadku możesz użyć pand.
x[~pandas.isna(x)] or x[~pandas.isnull(x)]
Odpowiedź Zaakceptowany zmienia kształt 2D tablic. Przedstawiam tutaj rozwiązanie, wykorzystujące funkcjonalność Panda Dropna () . Działa dla tablic 1D i 2D. W przypadku 2D możesz wybrać pogodę, aby upuścić wiersz lub kolumnę zawierającą 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='')
Wynik:
==================== 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.]
Najprostszym sposobem jest:
numpy.nan_to_num(x)
Dokumentacja: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html
NaN
s dużą liczbą, podczas gdy PO poprosił o całkowite usunięcie elementów.
To jest moje podejście do filtrowania ndarray „X” dla NaNs i infs,
Utworzyć mapę wierszy bez NaN
a każdy inf
, co następuje:
idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))
idx to krotka. Druga kolumna ( idx[1]
) zawiera indeksy tablicy, w których nie znaleziono NaN ani inf w poprzek wiersza.
Następnie:
filtered_X = X[idx[1]]
filtered_X
zawiera X bez NaN
nor inf
.
Odpowiedź @ jmetz jest prawdopodobnie najbardziej potrzebna; daje jednak jednowymiarową tablicę, np. uniemożliwia usunięcie całych wierszy lub kolumn w macierzach.
W tym celu należy zredukować tablicę logiczną do jednego wymiaru, a następnie zindeksować tablicę docelową. Na przykład następujące usunie wiersze, które mają co najmniej jedną wartość NaN:
x = x[~numpy.isnan(x).any(axis=1)]
Zobacz więcej szczegółów tutaj .