Se stai bene con numba permette di creare una funzione di cortocircuito veloce (si ferma non appena viene trovato un NaN):
import numba as nb
import math
@nb.njit
def anynan(array):
array = array.ravel()
for i in range(array.size):
if math.isnan(array[i]):
return True
return False
Se non c'è, NaN
la funzione potrebbe effettivamente essere più lenta di np.min
, penso che sia perché np.min
utilizza il multiprocessing per array di grandi dimensioni:
import numpy as np
array = np.random.random(2000000)
%timeit anynan(array) # 100 loops, best of 3: 2.21 ms per loop
%timeit np.isnan(array.sum()) # 100 loops, best of 3: 4.45 ms per loop
%timeit np.isnan(array.min()) # 1000 loops, best of 3: 1.64 ms per loop
Ma nel caso in cui ci sia un NaN nell'array, specialmente se la sua posizione è su indici bassi, allora è molto più veloce:
array = np.random.random(2000000)
array[100] = np.nan
%timeit anynan(array) # 1000000 loops, best of 3: 1.93 µs per loop
%timeit np.isnan(array.sum()) # 100 loops, best of 3: 4.57 ms per loop
%timeit np.isnan(array.min()) # 1000 loops, best of 3: 1.65 ms per loop
Risultati simili possono essere ottenuti con Cython o un'estensione C, questi sono un po 'più complicati (o facilmente disponibili come bottleneck.anynan
) ma alla fine fanno lo stesso della mia anynan
funzione.