Aby być jasnym, przez „usuń NaN” masz na myśli odfiltrowanie tylko podzbioru wartości niepustych . Nie „wypełniaj NaN pewną wartością (zero, stała, średnia, mediana itp.)”
smci,
Odpowiedzi:
362
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.isnanzwraca tablicę logiczną / logiczną, która ma wartość Truewszędzie, gdzie xnie jest liczbą. W przeciwieństwie do tego, używamy logicznego operatora, ~aby uzyskać tablicę Truezs wszędzie, gdzie xjest poprawna liczba.
Na koniec używamy tej tablicy logicznej do indeksowania do oryginalnej tablicy x, aby pobrać tylko wartości inne niż NaN.
Lub 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) == Falseoczywiście, ale ~numpy.isnan(numpy.inf) == True.
chbrown,
8
Dla osób, które chcą rozwiązać ten problem za pomocą ndarray i zachować wymiary, użyj numpy gdzie :np.where(np.isfinite(x), x, 0)
BoltzmannBrain
1
TypeError: tylko tablice skalarne liczb całkowitych mogą być konwertowane na indeks skalarny
towry
1
@towry: dzieje się tak, ponieważ dane wejściowe xnie są tablicami liczbowymi. Jeśli chcesz użyć indeksowania logicznego, musi to być tablica - np.x = np.array(x)
jmetz
50
filter(lambda v: v==v, x)
działa zarówno dla list, jak i tablicy numpy, ponieważ v! = v tylko dla NaN
Hack, ale szczególnie przydatny w przypadku, gdy filtrujesz nans z tablicy obiektów o mieszanych typach, takich jak łańcuchy i nans.
Austin Richardson
Bardzo czyste rozwiązanie.
Moondra
2
Może się to wydawać sprytne, ale jeśli zasłania logikę i teoretycznie inne obiekty (takie jak klasy niestandardowe) mogą również mieć tę właściwość
Chris_Rands
Przydatny również, ponieważ należy xgo podać tylko raz, w przeciwieństwie do rozwiązań tego typu x[~numpy.isnan(x)]. Jest to wygodne, gdy xjest zdefiniowane długim wyrażeniem i nie chcesz zaśmiecać kodu, tworząc tymczasową zmienną do przechowywania wyniku tego długiego wyrażenia.
Christian O'Reilly,
34
Spróbuj tego:
import math
print[value for value in x ifnot math.isnan(value)]
Aby uzyskać więcej informacji, zapoznaj się z listami .
Jeśli używasz numpy, zarówno moja odpowiedź, jak i @ @ lazy1 są prawie o rząd wielkości szybsze niż zrozumienie listy - rozwiązanie lazy1 jest nieco szybsze (choć technicznie nie zwróci również żadnych wartości nieskończoności).
jmetz
Nie zapomnij o nawiasach :)print ([value for value in x if not math.isnan(value)])
odsyła
Jeśli używasz numpy jak najwyższej odpowiedzi, możesz użyć tej odpowiedzi ze zrozumieniem listy w nppakiecie: Więc zwraca listę bez nans:[value for value in x if not np.isnan(value)]
yeliabsalohcin
23
Dla mnie odpowiedź @jmetz nie działała, jednak użycie pandas isnull () działało.
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
To jest dziwne; zgodnie z dokumentacją indeksowanie tablic boolowskich (które to jest), podlega zaawansowanemu indeksowaniu, które najwyraźniej „zawsze zwraca kopię danych”, dlatego należy xnadpisywać nową wartością (tj. bez NaNs ...) . Czy możesz podać więcej informacji, dlaczego tak się dzieje?
jmetz
5
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.
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:
====================1DCase:====================Input:[1400.1500.1600. nan nan nan 1700.]
dropna:[1400.1500.1600.1700.]====================2DCase:====================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))]for2D:====================Input:[[1400.1500.1600.][ nan 0. nan][1700.1800. nan]]
dropna:[1400.1500.1600.1700.]
Witamy w SO! Rozwiązanie, które proponujesz, nie rozwiązuje problemu: twoje rozwiązanie zastępuje NaNs dużą liczbą, podczas gdy PO poprosił o całkowite usunięcie elementów.
Pier Paolo
0
To jest moje podejście do filtrowania ndarray „X” dla NaNs i infs,
Utworzyć mapę wierszy bez NaNa każdy inf, co następuje:
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:
Odpowiedzi:
Jeśli używasz numpy do swoich tablic, możesz także użyć
Równoważnie
[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, gdziex
nie jest liczbą. W przeciwieństwie do tego, używamy logicznego operatora,~
aby uzyskać tablicęTrue
zs wszędzie, gdziex
jest poprawna liczba.Na koniec używamy tej tablicy logicznej do indeksowania do oryginalnej tablicy
x
, aby pobrać tylko wartości inne niż NaN.źródło
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 tymnumpy.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)
działa zarówno dla list, jak i tablicy numpy, ponieważ v! = v tylko dla NaN
źródło
x
go podać tylko raz, w przeciwieństwie do rozwiązań tego typux[~numpy.isnan(x)]
. Jest to wygodne, gdyx
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:
Aby uzyskać więcej informacji, zapoznaj się z listami .
źródło
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.
źródło
Wykonując powyższe:
lub
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
źródło
x
nadpisywać nową wartością (tj. bez NaNs ...) . Czy możesz podać więcej informacji, dlaczego tak się dzieje?Jak pokazują inni
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.
źródło
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
.Wynik:
źródło
Jeśli używasz
numpy
źródło
Najprostszym sposobem jest:
Dokumentacja: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html
źródło
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żdyinf
, co następuje: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
zawiera X bezNaN
norinf
.źródło
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:
Zobacz więcej szczegółów tutaj .
źródło