En complément des réponses de @nico-schlömer et @mseifert, j'ai calculé la performance d'un numba-test has_nan
avec des arrêts précoces, par rapport à certaines fonctions qui analysent le tableau complet.
Sur ma machine, pour un tableau sans nans, le seuil de rentabilité est atteint pour ~10^4 éléments.
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)",
)
Que se passe-t-il si le tableau a des nans ? J'ai étudié l'impact de la couverture nanométrique du réseau.
Pour les tableaux de longueur 1 000 000, has_nan
devient une meilleure option s'il y a ~10^-3 % de nans (donc ~10 nans) dans le tableau.
#%%
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})",
)
Si, dans votre application, la plupart des tableaux ont nan
et que vous en recherchez d'autres qui n'en ont pas, alors has_nan
est la meilleure approche. Autre ; dot
semble être la meilleure option.
0 votes
La validation de l'entrée de l'utilisateur ne fonctionne-t-elle pas dans ce scénario ? Comme dans le cas d'une vérification de NaN avant l'insertion.
0 votes
@Woot4Moo : non, la bibliothèque prend les tableaux NumPy ou
scipy.sparse
en tant que données d'entrée.2 votes
Si vous faites cela souvent, j'ai entendu de bonnes choses à propos de Bottleneck ( pypi.python.org/pypi/Bottleneck )