Je recherche le moyen le plus rapide de vérifier l'occurrence de NaN ( np.nan
) dans un tableau NumPy X
. np.isnan(X)
est hors de question, car il construit un tableau booléen de forme X.shape
, ce qui est potentiellement gigantesque.
J'ai essayé np.nan in X
, mais cela ne semble pas fonctionner parce que np.nan != np.nan
. Existe-t-il un moyen rapide et efficace de faire cela?
(À ceux qui demanderaient «à quel point c'est gigantesque»: je ne peux pas le dire. C'est la validation d'entrée pour le code de la bibliothèque.)
scipy.sparse
en entrée des tableaux ou des matrices NumPy .Réponses:
La solution de Ray est bonne. Cependant, sur ma machine, il est environ 2,5 fois plus rapide à utiliser
numpy.sum
à la place denumpy.min
:Contrairement à
min
,sum
ne nécessite pas de branchement, ce qui sur le matériel moderne a tendance à être assez coûteux. C'est probablement la raison pour laquellesum
c'est plus rapide.edit Le test ci-dessus a été effectué avec un seul NaN en plein milieu du tableau.
Il est intéressant de noter que
min
c'est plus lent en présence de NaN qu'en leur absence. Il semble également devenir plus lent à mesure que les NaN se rapprochent du début du tableau. D'un autre côté,sum
le débit semble constant, qu'il y ait ou non des NaN et où ils se trouvent:la source
np.min
est plus rapide lorsque le tableau ne contient pas de NaN, ce qui est mon entrée attendue. Mais j'ai quand même décidé d'accepter celui-ci, car il attrapeinf
etneginf
aussi.inf
ou-inf
si l'entrée contient à la fois, et il a des problèmes si l'entrée contient de grandes valeurs , mais finies qui débordent lorsqu'ils sont additionnés.np.sum
est toujours environ 30% plus rapide quenp.min
.np.isnan(x).any(0)
est légèrement plus rapide quenp.sum
etnp.min
sur ma machine, bien qu'il puisse y avoir une mise en cache indésirable.Je pense
np.isnan(np.min(X))
que tu devrais faire ce que tu veux.la source
Même s'il existe une réponse acceptée, j'aimerais démontrer ce qui suit (avec Python 2.7.2 et Numpy 1.6.0 sur Vista):
Ainsi, la manière vraiment efficace pourrait dépendre fortement du système d'exploitation. Quoi qu'il en soit,
dot(.)
basé semble être le plus stable.la source
x
contient de grandes valeurs, et je souhaite également vérifier les inf.isfinite(.)
. Je voulais juste souligner l'énorme écart de performance. Mercimin
- ou lessum
approches à base, qui vont limités à un seul noyau. Ergo, cet écart de performance.Il existe deux approches générales ici:
nan
et prenezany
.nan
s (commesum
) et vérifiez son résultat.Alors que la première approche est certainement la plus propre, l'optimisation lourde de certaines des opérations cumulatives (en particulier celles qui sont exécutées dans BLAS, par exemple
dot
) peut les rendre assez rapides. Notez quedot
, comme certaines autres opérations BLAS, sont multithread sous certaines conditions. Ceci explique la différence de vitesse entre les différentes machines.la source
utiliser .any ()
if numpy.isnan(myarray).any()
numpy.isfinite peut-être mieux que isnan pour vérifier
if not np.isfinite(prop).all()
la source
Si vous êtes à l'aise avec numba il permet de créer une fonction de court-circuit rapide (s'arrête dès qu'un NaN est trouvé):
S'il n'y a pas,
NaN
la fonction pourrait en fait être plus lente quenp.min
, je pense que c'est parce quenp.min
utilise le multitraitement pour les grands tableaux:Mais au cas où il y aurait un NaN dans le tableau, surtout si sa position est à des indices bas, alors c'est beaucoup plus rapide:
Des résultats similaires peuvent être obtenus avec Cython ou une extension C, ceux-ci sont un peu plus compliqués (ou facilement disponibles en tant que
bottleneck.anynan
) mais font finalement la même chose que maanynan
fonction.la source
Liée à ceci est la question de savoir comment trouver la première occurrence de NaN. C'est le moyen le plus rapide de gérer ce que je connais:
la source