J'ai besoin de calculer le nombre d'éléments non-NaN dans une matrice numpy-ndarray. Comment ferait-on cela efficacement en Python? Voici mon code simple pour y parvenir:
import numpy as np
def numberOfNonNans(data):
count = 0
for i in data:
if not np.isnan(i):
count += 1
return count
Existe-t-il une fonction intégrée pour cela dans numpy? L'efficacité est importante car je suis en train d'analyser le Big Data.
Merci pour toute aide!
np.count_nonzero(~np.isnan(data))
~
Inverse la matrice booléenne renvoyée par np.isnan
.
np.count_nonzero
Compte les valeurs qui ne sont pas 0\false. .sum
Devrait donner le même résultat. Mais peut-être plus clairement d'utiliser count_nonzero
Vitesse d'essai:
In [23]: data = np.random.random((10000,10000))
In [24]: data[[np.random.random_integers(0,10000, 100)],:][:, [np.random.random_integers(0,99, 100)]] = np.nan
In [25]: %timeit data.size - np.count_nonzero(np.isnan(data))
1 loops, best of 3: 309 ms per loop
In [26]: %timeit np.count_nonzero(~np.isnan(data))
1 loops, best of 3: 345 ms per loop
In [27]: %timeit data.size - np.isnan(data).sum()
1 loops, best of 3: 339 ms per loop
data.size - np.count_nonzero(np.isnan(data))
semble être à peine le plus rapide ici. d'autres données peuvent donner des résultats de vitesse relative différents.
Même si ce n’est pas le choix le plus rapide, si les performances ne sont pas un problème, vous pouvez utiliser:
sum(~np.isnan(data))
.
In [7]: %timeit data.size - np.count_nonzero(np.isnan(data))
10 loops, best of 3: 67.5 ms per loop
In [8]: %timeit sum(~np.isnan(data))
10 loops, best of 3: 154 ms per loop
In [9]: %timeit np.sum(~np.isnan(data))
10 loops, best of 3: 140 ms per loop
Une alternative, mais un peu plus lente, consiste à le faire sur l’indexation.
np.isnan(data)[np.isnan(data) == False].size
In [30]: %timeit np.isnan(data)[np.isnan(data) == False].size
1 loops, best of 3: 498 ms per loop
La double utilisation de np.isnan(data)
et de l'opérateur ==
Est peut-être un peu exagérée et j'ai donc posté la réponse uniquement par souci d'exhaustivité.
Pour déterminer si le tableau est rare, il peut être utile d’obtenir une proportion de nan
np.isnan(ndarr).sum() / ndarr.size
Si cette proportion dépasse un seuil, utilisez un tableau fragmenté, par ex. - https://sparse.pydata.org/en/latest/