151 votes

numpy get index où la valeur est vraie

>>> ex=np.arange(30)
>>> e=np.reshape(ex,[3,10])
>>> e
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]])
>>> e>15
array([[False, False, False, False, False, False, False, False, False,
        False],
       [False, False, False, False, False, False,  True,  True,  True,
         True],
       [ True,  True,  True,  True,  True,  True,  True,  True,  True,
         True]], dtype=bool)

J'ai besoin de trouver les lignes qui ont true ou les lignes en e dont la valeur est supérieure à 15. Je pourrais itérer en utilisant une boucle for, mais j'aimerais savoir s'il existe un moyen pour numpy de faire cela plus efficacement ?

131voto

Jaime Points 25540

Pour obtenir les numéros de ligne où au moins un élément est supérieur à 15 :

>>> np.where(np.any(e>15, axis=1))
(array([1, 2], dtype=int64),)

90voto

Constantine Points 833

Vous pouvez utiliser le nonzero La fonction renvoie les indices non nuls de l'entrée donnée.

Méthode simple

>>> (e > 15).nonzero()

(array([1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]), array([6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))

pour voir les indices plus proprement, utilisez transpose méthode :

>>> numpy.transpose((e>15).nonzero())

[[1 6]
 [1 7]
 [1 8]
 [1 9]
 [2 0]
 ...

Pas mal de manières

>>> numpy.nonzero(e > 15)

(array([1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]), array([6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))

ou la manière propre :

>>> numpy.transpose(numpy.nonzero(e > 15))

[[1 6]
 [1 7]
 [1 8]
 [1 9]
 [2 0]
 ...

52voto

Opt Points 150

Un moyen simple et propre : utiliser np.argwhere pour regrouper les indices par élément, plutôt que par dimension comme dans np.nonzero(a) (c'est-à-dire, np.argwhere renvoie une ligne pour chaque élément non nul).

>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.argwhere(a>4)
array([[5],
       [6],
       [7],
       [8],
       [9]])

np.argwhere(a) est presque identique à np.transpose(np.nonzero(a)) mais il produit un résultat de la forme correcte pour un tableau 0-d.

Nota: Vous ne pouvez pas utiliser a(np.argwhere(a>4)) pour obtenir les valeurs correspondantes dans a . La méthode recommandée est d'utiliser a[(a>4).astype(bool)] o a[(a>4) != 0] plutôt que a[np.nonzero(a>4)] car ils gèrent correctement les tableaux 0-d. Voir le documentation pour plus de détails. Comme on peut le voir dans l'exemple suivant, a[(a>4).astype(bool)] y a[(a>4) != 0] peut être simplifié en a[a>4] .

Un autre exemple :

>>> a = np.array([5,-15,-8,-5,10])
>>> a
array([  5, -15,  -8,  -5,  10])
>>> a > 4
array([ True, False, False, False,  True])
>>> a[a > 4]
array([ 5, 10])
>>> a = np.add.outer(a,a)
>>> a
array([[ 10, -10,  -3,   0,  15],
       [-10, -30, -23, -20,  -5],
       [ -3, -23, -16, -13,   2],
       [  0, -20, -13, -10,   5],
       [ 15,  -5,   2,   5,  20]])
>>> a = np.argwhere(a>4)
>>> a
array([[0, 0],
       [0, 4],
       [3, 4],
       [4, 0],
       [4, 3],
       [4, 4]])
>>> for i,j in a: print(i,j)
... 
0 0
0 4
3 4
4 0
4 3
4 4
>>>

0voto

crypdick Points 837

Je préfère np.flatnonzero(arr) a la nonzero() lorsque vous n'avez besoin que de l'idx de la ligne. arr.nonzero() fonctionne, mais elle renvoie un tuple au lieu d'un tableau. flatnonzero() est équivalent à np.nonzero(np.ravel(arr))[0] .

Comme mentionné dans les commentaires, np.where() est déconseillée par la documentation de NumPy.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X