Comprendre numpy.where

Oct 19 2020

Je veux obtenir le premier index de l'élément de tableau numpy qui est supérieur à un élément spécifique de ce même tableau. J'ai essayé de suivre:

>>> Q5=[[1,2,3],[4,5,6]]
>>> Q5 = np.array(Q5)
>>> Q5[0][Q5>Q5[0,0]]
array([2, 3])
>>> np.where(Q5[0]>Q5[0,0])
(array([1, 2], dtype=int32),)
>>> np.where(Q5[0]>Q5[0,0])[0][0]
1

Q1. La méthode ci-dessus est-elle correcte pour obtenir le premier index d'un élément Q5[0]supérieur à Q5[0,0]?

Je suis plus préoccupé par le np.where(Q5[0]>Q5[0,0])retour de tuple (array([1, 2], dtype=int32),)et par conséquent, je me demande de doubler l'index [0][0]à la fin de np.where(Q5[0]>Q5[0,0])[0][0].

Q2. Pourquoi ce tuple de retour, mais ci-dessous renvoie un tableau numpy approprié?

>>> np.where(Q5[0]>Q5[0,0],Q5[0],-1)
array([-1,  2,  3])

Pour que je puisse indexer directement:

>>> np.where(Q5[0]>Q5[0,0],Q5[0],-1)[1]
2

Réponses

hpaulj Oct 19 2020 at 21:42
In [58]: A = np.arange(1,10).reshape(3,3)
In [59]: A.shape
Out[59]: (3, 3)
In [60]: A
Out[60]: 
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

np.whereavec juste la condition est vraiment np.nonzero.

Générez un tableau booléen:

In [63]: A==6
Out[63]: 
array([[False, False, False],
       [False, False,  True],
       [False, False, False]])

Trouvez où cela est vrai:

In [64]: np.nonzero(A==6)
Out[64]: (array([1]), array([2]))

Le résultat est un tuple, un élément par dimension de la condition. Chaque élément est un tableau d'indexation, ensemble ils définissent l'emplacement du ou des True (s)

Un autre test avec plusieurs True

In [65]: (A%3)==1
Out[65]: 
array([[ True, False, False],
       [ True, False, False],
       [ True, False, False]])
In [66]: np.nonzero((A%3)==1)
Out[66]: (array([0, 1, 2]), array([0, 0, 0]))

Utilisation du tuple pour indexer le tableau d'origine:

In [67]: A[np.nonzero((A%3)==1)]
Out[67]: array([1, 4, 7])

Utilisation de l'argument 3 wherepour créer un nouveau tableau avec un mélange de valeurs de AetA+10

In [68]: np.where((A%3)==1,A+10, A)
Out[68]: 
array([[11,  2,  3],
       [14,  5,  6],
       [17,  8,  9]])

Si la condition a plusieurs True, nonzeron'est pas l'outil de test pour trouver le "premier", car il trouve nécessairement tout.

Le tuple différent de zéro peut être transformé en un tableau 2d avec un transpose. Il peut en fait être plus facile d'obtenir le «premier» de ce tableau:

In [73]: np.argwhere((A%3)==1)
Out[73]: 
array([[0, 0],
       [1, 0],
       [2, 0]])

Vous recherchez dans un tableau 1d, une ligne de A:

In [77]: A[0]>A[0,0]
Out[77]: array([False,  True,  True])
In [78]: np.nonzero(A[0]>A[0,0])
Out[78]: (array([1, 2]),)            # 1 element tuple
In [79]: np.argwhere(A[0]>A[0,0])
Out[79]: 
array([[1],
       [2]])
In [81]: np.where(A[0]>A[0,0], 100, 0)     # 3 argument where
Out[81]: array([  0, 100, 100])

Ainsi, que vous recherchiez un tableau 1d ou un 2d (ou 3 ou 4), nonzerorenvoie un tuple avec un élément de tableau par dimension. De cette façon, il peut toujours être utilisé pour indexer un tableau de taille similaire. Le tuple 1d peut sembler redondant, mais il est cohérent avec d'autres résultats dimensionnels.

Lorsque vous essayez de comprendre des opérations comme celle-ci, lisez attentivement la documentation et examinez les étapes individuelles. Ici, je regarde la matrice conditionnelle, le nonzerorésultat et ses différentes utilisations.

AsafH Oct 19 2020 at 22:05

numpy.where () est comme une boucle for avec un if.

numpy.where(condition, values, new_value)

condition - tout comme si conditions.
values - Les valeurs à itérer sur
new_value - si la condition est vraie pour une valeur , elle va changer en new_value


Si nous voulons l'écrire pour un tableau à 1 dimension, cela devrait ressembler à ceci:
[xv if c else yv 
for c, xv, yv in zip(condition, x, y)]

Exemple:

>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.where(a < 5, a, 10*a)
array([ 0,  1,  2,  3,  4, 50, 60, 70, 80, 90])

Nous créons d'abord un tableau avec des nombres de 0 à 9 (0, 1, 2 ... 7, 8, 9)
, puis nous vérifions toutes les valeurs du tableau qui sont supérieures à 5 et en multipliant leur valeur par 10.
Alors maintenant, toutes les valeurs du tableau inférieures à 5 sont restées les mêmes et toutes les valeurs supérieures multipliées par 10

wwii Oct 19 2020 at 21:41

L'utilisation argmaxavec un tableau booléen vous donnera l'index du premier True.

In [54]: q
Out[54]: 
array([[1, 2, 3],
       [4, 5, 6]])

In [55]: q > q[0,0]
Out[55]: 
array([[False,  True,  True],
       [ True,  True,  True]], dtype=bool)

argmax peut prendre un argument axe / dimension.

In [56]: np.argmax(q > q[0,0], 0)
Out[56]: array([1, 0, 0], dtype=int64)

Cela dit que le premier True est l'index un pour la colonne zéro et l'index zéro pour les colonnes un et deux.

In [57]: np.argmax(q > q[0,0], 1)
Out[57]: array([1, 0], dtype=int64)

Cela dit que le premier True est l'index un pour la ligne zéro et l'index zéro pour la ligne un.


Q1. La manière ci-dessus est-elle correcte d'obtenir le premier indice d'un élément dans Q5 [0] supérieur à Q5 [0,0]?

Non, je voudrais utiliser argmaxavec 1pour l' axisargument puis sélectionner le premier élément de ce résultat.

Q2. Pourquoi ce tuple de retour

Vous lui avez dit de retourner -1pour les valeurs False et de renvoyer des Q5[0]éléments pour les valeurs True.

Q2 ... mais ci-dessous renvoie le tableau numpy approprié?

Vous avez eu de la chance et avez choisi le bon index.