Если вас устраивает numba , это позволяет создать функцию быстрого короткого замыкания (останавливается, как только обнаружен 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
Если нет NaN
, функция может быть на самом деле медленнее, чем np.min
, я думаю, это потому, что np.min
использует многопроцессорную обработку для больших массивов:
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
Но если в массиве есть NaN, особенно если его позиция с низкими индексами, то это происходит намного быстрее:
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
Подобные результаты могут быть достигнуты с Cython или расширением C, они немного сложнее (или легко доступны, как bottleneck.anynan
), но в конечном итоге делают то же самое, что и моя anynan
функция.