Trouver des indices d'éléments égaux à zéro dans un tableau NumPy


144

NumPy a la fonction / méthode efficace nonzero()pour identifier les indices d'éléments non nuls dans un ndarrayobjet. Quelle est la manière la plus efficace d'obtenir les indices des éléments qui faire une valeur de zéro?

Réponses:


226

numpy.where () est mon préféré.

>>> x = numpy.array([1,0,2,0,3,0,4,5,6,7,8])
>>> numpy.where(x == 0)[0]
array([1, 3, 5])

16
J'essaye de me souvenir de Python. Pourquoi where()renvoie un tuple? numpy.where(x == 0)[1]est hors limites. à quoi le tableau d'index est-il alors couplé?
Zhubarb

@Zhubarb - La plupart des utilisations des indéces sont des tuples - np.zeros((3,))pour créer un vecteur de 3 longueurs par exemple. Je soupçonne que c'est pour faciliter l'analyse des paramètres. Sinon, quelque chose comme np.zeros(3,0,dtype='int16')versus np.zeros(3,3,3,dtype='int16')serait ennuyeux à mettre en œuvre.
mtrw

5
non. whererenvoie un tuple de ndarrays, chacun d'eux correspondant à une dimension de l'entrée. dans ce cas, l'entrée est un tableau, donc la sortie est un 1-tuple. Si x était une matrice, ce serait un 2-tuple, et ainsi de suite
Ciprian Tomoiagă

1
Depuis numpy 1.16, la documentation denumpy.where recommande spécifiquement d'utiliser numpy.nonzerodirectement plutôt que d'appeler whereavec un seul argument.
jirassimok

@jirassimok comment utilisez-vous une valeur non nulle pour trouver des zéros comme la question le demande?
mLstudent33

28

Il y a np.argwhere,

import numpy as np
arr = np.array([[1,2,3], [0, 1, 0], [7, 0, 2]])
np.argwhere(arr == 0)

qui renvoie tous les indices trouvés sous forme de lignes:

array([[1, 0],    # Indices of the first zero
       [1, 2],    # Indices of the second zero
       [2, 1]],   # Indices of the third zero
      dtype=int64)

23

Vous pouvez rechercher n'importe quelle condition scalaire avec:

>>> a = np.asarray([0,1,2,3,4])
>>> a == 0 # or whatver
array([ True, False, False, False, False], dtype=bool)

Ce qui rendra le tableau comme un masque booléen de la condition.


1
Vous pouvez l'utiliser pour accéder aux éléments zéro:a[a==0] = epsilon
Quant Metropolis

17

Vous pouvez également l'utiliser nonzero()en l'utilisant sur un masque booléen de la condition, car Falsec'est aussi une sorte de zéro.

>>> x = numpy.array([1,0,2,0,3,0,4,5,6,7,8])

>>> x==0
array([False, True, False, True, False, True, False, False, False, False, False], dtype=bool)

>>> numpy.nonzero(x==0)[0]
array([1, 3, 5])

Il fait exactement la même chose que mtrwla manière de, mais c'est plus lié à la question;)


Cela devrait être la réponse acceptée car il s'agit de l'utilisation conseillée de la nonzerométhode pour vérifier les conditions.
sophros

5

Vous pouvez utiliser numpy.nonzero pour trouver zéro.

>>> import numpy as np
>>> x = np.array([1,0,2,0,3,0,0,4,0,5,0,6]).reshape(4, 3)
>>> np.nonzero(x==0)  # this is what you want
(array([0, 1, 1, 2, 2, 3]), array([1, 0, 2, 0, 2, 1]))
>>> np.nonzero(x)
(array([0, 0, 1, 2, 3, 3]), array([0, 2, 1, 1, 0, 2]))

4

Si vous travaillez avec un tableau unidimensionnel, il existe un sucre syntaxique:

>>> x = numpy.array([1,0,2,0,3,0,4,5,6,7,8])
>>> numpy.flatnonzero(x == 0)
array([1, 3, 5])

Cela fonctionne bien tant que je n'ai qu'une seule condition. Que faire si je souhaite rechercher "x == numpy.array (0,2,7)"? Le résultat doit être array ([1,2,3,5,9]). Mais comment puis-je l'obtenir?
MoTSCHIGGE

Vous pouvez le faire avec:numpy.flatnonzero(numpy.logical_or(numpy.logical_or(x==0, x==2), x==7))
Dusch

1
import numpy as np

x = np.array([1,0,2,3,6])
non_zero_arr = np.extract(x>0,x)

min_index = np.amin(non_zero_arr)
min_value = np.argmin(non_zero_arr)

1

Je le ferais de la manière suivante:

>>> x = np.array([[1,0,0], [0,2,0], [1,1,0]])
>>> x
array([[1, 0, 0],
       [0, 2, 0],
       [1, 1, 0]])
>>> np.nonzero(x)
(array([0, 1, 2, 2]), array([0, 1, 0, 1]))

# if you want it in coordinates
>>> x[np.nonzero(x)]
array([1, 2, 1, 1])
>>> np.transpose(np.nonzero(x))
array([[0, 0],
       [1, 1],
       [2, 0],
       [2, 1])
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.