除了 @nico-schlömer 和 @mseifert 的答案之外,我还计算了带有提前停止的 numba-test has_nan 的性能,与解析整个数组的一些函数相比。
在我的机器上,对于没有 nans 的数组,收支平衡发生在 ~10^4 个元素。
import perfplot
import numpy as np
import numba
import math
def min(a):
return np.isnan(np.min(a))
def dot(a):
return np.isnan(np.dot(a, a))
def einsum(a):
return np.isnan(np.einsum("i->", a))
@numba.njit
def has_nan(a):
for i in range(a.size - 1):
if math.isnan(a[i]):
return True
return False
def array_with_missing_values(n, p):
""" Return array of size n, p : nans ( % of array length )
Ex : n=1e6, p=1 : 1e4 nan assigned at random positions """
a = np.random.rand(n)
p = np.random.randint(0, len(a), int(p*len(a)/100))
a[p] = np.nan
return a
#%%
perfplot.show(
setup=lambda n: array_with_missing_values(n, 0),
kernels=[min, dot, has_nan],
n_range=[2 ** k for k in range(20)],
logx=True,
logy=True,
xlabel="len(a)",
)
如果数组有 nans 会发生什么?我调查了数组的 nan-coverage 的影响。
对于长度为 1,000,000 的数组,has_nan 成为更好的选择,因为数组中有 ~10^-3 % nans(所以 ~10 nans)。
#%%
N = 1000000 # 100000
perfplot.show(
setup=lambda p: array_with_missing_values(N, p),
kernels=[min, dot, has_nan],
n_range=np.array([2 ** k for k in range(20)]) / 2**20 * 0.01,
logy=True,
xlabel=f"% of nan in array (N = {N})",
)
如果在您的应用程序中大多数数组都有nan,而您正在寻找没有的数组,那么has_nan 是最好的方法。
别的; dot 似乎是最好的选择。