web-dev-qa-db-fra.com

Compter efficacement zéro élément dans le tableau numpy?

Je dois compter le nombre d'éléments nuls dans les tableaux numpy. Je suis conscient de la fonction numpy.count_nonzero , mais il ne semble pas exister d'analogique pour compter les éléments nuls.

Mes tableaux ne sont pas très grands (généralement moins de 1E5 éléments), mais l'opération est effectuée plusieurs millions de fois.

Bien sûr, je pourrais utiliser len(arr) - np.count_nonzero(arr), mais je me demande s’il existe un moyen plus efficace de le faire.

Voici un MWE de la façon dont je le fais actuellement:

import numpy as np
import timeit

arrs = []
for _ in range(1000):
    arrs.append(np.random.randint(-5, 5, 10000))


def func1():
    for arr in arrs:
        zero_els = len(arr) - np.count_nonzero(arr)


print(timeit.timeit(func1, number=10))
19
Gabriel

Une approche un peu plus rapide consisterait à utiliser simplement np.count_nonzero() mais avec la condition nécessaire.

In [3]: arr
Out[3]: 
array([[1, 2, 0, 3],
      [3, 9, 0, 4]])

In [4]: np.count_nonzero(arr==0)
Out[4]: 2

In [5]:def func_cnt():
            for arr in arrs:
                zero_els = np.count_nonzero(arr==0)
                # here, it counts the frequency of zeroes actually

Vous pouvez également utiliser np.where mais c'est plus lent que np.count_nonzero()

In [6]: np.where( arr == 0)
Out[6]: (array([0, 1]), array([2, 2]))

In [7]: len(np.where( arr == 0))
Out[7]: 2

Efficiency: (par ordre décroissant)

In [8]: %timeit func_cnt()
10 loops, best of 3: 29.2 ms per loop

In [9]: %timeit func1()
10 loops, best of 3: 46.5 ms per loop

In [10]: %timeit func_where()
10 loops, best of 3: 61.2 ms per loop
27
kmario23