Szukam najszybszego sposobu, aby sprawdzić wystąpienie NaN ( np.nan
) w tablicy NumPy X
. np.isnan(X)
nie wchodzi w rachubę, ponieważ buduje boolowską tablicę kształtów X.shape
, która jest potencjalnie gigantyczna.
Próbowałem np.nan in X
, ale to nie działa, ponieważ np.nan != np.nan
. Czy w ogóle istnieje szybki i oszczędzający pamięć sposób, aby to zrobić?
(Do tych, którzy pytają „jak gigantyczne”: nie mogę powiedzieć. To jest walidacja danych wejściowych dla kodu biblioteki).
scipy.sparse
macierze NumPy jako dane wejściowe.Odpowiedzi:
Rozwiązanie Raya jest dobre. Jednak na moim komputerze jest około 2,5x szybszy w użyciu
numpy.sum
zamiastnumpy.min
:W przeciwieństwie
min
,sum
nie wymaga rozgałęzienia, które na nowoczesnym sprzęcie wydaje się być dość kosztowne. To jest prawdopodobnie powód, dla któregosum
jest szybszy.edit Powyższy test został przeprowadzony z pojedynczym NaN w środku tablicy.
Warto zauważyć, że
min
jest wolniejszy w obecności NaN niż w przypadku ich braku. Wydaje się również, że działa wolniej, gdy NaN zbliżają się do początku tablicy. Z drugiej stronysum
przepustowość wydaje się stała, niezależnie od tego, czy istnieją NaN i gdzie się znajdują:źródło
np.min
jest szybszy, gdy tablica nie zawiera NaN, co jest moim oczekiwanym wejściem. Ale i tak zdecydowałem się to zaakceptować, ponieważ łapieinf
ineginf
też.inf
lub-inf
jeśli dane wejściowe zawierają oba, i występują problemy, jeśli dane wejściowe zawierają duże, ale skończone wartości, które po dodaniu przepełniają się.np.sum
jest nadal około 30% szybszy niżnp.min
.np.isnan(x).any(0)
jest nieco szybszy niżnp.sum
inp.min
na moim komputerze, chociaż może występować niechciane buforowanie.Myślę, że
np.isnan(np.min(X))
powinienem robić, co chcesz.źródło
Nawet jeśli istnieje akceptowana odpowiedź, chciałbym zademonstrować co następuje (w Pythonie 2.7.2 i Numpy 1.6.0 w systemie Vista):
Tak więc naprawdę skuteczny sposób może w dużym stopniu zależeć od systemu operacyjnego. W każdym razie
dot(.)
oparty wydaje się być najbardziej stabilny.źródło
x
zawiera duże wartości, i chcę również sprawdzić inf.isfinite(.)
. Chciałem tylko zwrócić uwagę na ogromną różnicę w wydajności. Dziękimin
- lubsum
, które są ograniczone do jednego rdzenia. Ergo, ta różnica w wydajności.Istnieją dwa ogólne podejścia:
nan
i weźany
.nan
s (likesum
) i sprawdź jej wynik.Chociaż pierwsze podejście jest z pewnością najczystsze, ciężka optymalizacja niektórych skumulowanych operacji (szczególnie tych, które są wykonywane w BLAS, jak np.
dot
) Może sprawić, że będą one dość szybkie. Zauważ, żedot
podobnie jak niektóre inne operacje BLAS, w pewnych warunkach są wielowątkowe. To wyjaśnia różnicę w prędkości między różnymi maszynami.źródło
use .any ()
if numpy.isnan(myarray).any()
numpy.isfinite może lepiej niż isnan do sprawdzenia
if not np.isfinite(prop).all()
źródło
Jeśli czujesz się komfortowo z numba pozwala na stworzenie szybkiego zwarcia (zatrzymuje się po znalezieniu NaN) funkcja:
Jeśli nie ma
NaN
funkcji, może być wolniejsza niżnp.min
, myślę, że to dlatego, żenp.min
używa przetwarzania wieloprocesowego dla dużych tablic:Ale jeśli w tablicy znajduje się NaN, zwłaszcza jeśli jego pozycja znajduje się na niskich indeksach, jest to znacznie szybsze:
Podobne wyniki można osiągnąć z Cythonem lub rozszerzeniem C, są one nieco bardziej skomplikowane (lub łatwo dostępne
bottleneck.anynan
), ale ostatecznie robią to samo, co mojaanynan
funkcja.źródło
Wiąże się z tym pytanie, jak znaleźć pierwsze wystąpienie NaN. To najszybszy sposób radzenia sobie z tym, o czym wiem:
źródło