Se você está confortável com numba permite criar uma função de curto-circuito rápido (para assim que um NaN for encontrado):
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 não houver nenhuma, NaN
a função pode realmente ser mais lenta do que np.min
, acho que é porque np.min
usa multiprocessamento para grandes matrizes:
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
Mas, caso haja um NaN na matriz, especialmente se sua posição estiver em índices baixos, é muito mais rápido:
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
Resultados semelhantes podem ser alcançados com Cython ou uma extensão C, eles são um pouco mais complicados (ou facilmente disponíveis como bottleneck.anynan
), mas no final das contas fazem o mesmo que minha anynan
função.