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?

gotgenes
la source

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])
mtrw
la source
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)
MSeifert
la source
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.

nate c
la source
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;)

Crépuscule
la source
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]))
chmnsk
la source
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])
dvdvck
la source
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)
sramij
la source
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])
Jeril
la source