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, NaNa função pode realmente ser mais lenta do que np.min, acho que é porque np.minusa 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 anynanfunção.