Comment est Python num PY?où ()?

je joue avec numpy et je creuse dans la documentation et je suis tombé sur de la magie. À savoir je parle de numpy.where() :

>>> x = np.arange(9.).reshape(3, 3)
>>> np.where( x > 5 )
(array([2, 2, 2]), array([0, 1, 2]))

comment peuvent-ils réaliser à l'interne que vous êtes capable de passer quelque chose comme x > 5 dans une méthode? Je suppose que ça a quelque chose à voir avec __gt__ mais je cherche une explication détaillée.

88
demandé sur JasonMArcher 2011-04-13 02:39:26

3 réponses

comment parviennent-ils à l'intérieur que vous êtes capable de passer quelque chose comme x > 5 dans une méthode?

la réponse courte est qu'ils ne le font pas.

Toute sorte d'opération logique sur un tableau numpy retourne un booléen tableau. (i.e. __gt__ , __lt__ , etc tous les tableaux booléens de retour où la condition donnée est vraie).

E. G.

x = np.arange(9).reshape(3,3)
print x > 5

les rendements:

array([[False, False, False],
       [False, False, False],
       [ True,  True,  True]], dtype=bool)

C'est la même raison pour laquelle quelque chose comme if x > 5: soulève une Valeurerror si x est un numpy array. C'est un tableau de valeurs True/False, pas une seule valeur.

de plus, les tableaux numpy peuvent être indexés par des tableaux booléens. E. g. x[x>5] rendements [6 7 8] , dans ce cas.

Honnêtement, il est assez rare que vous avez réellement besoin de numpy.where mais il renvoie juste les indices où un booléen array est True . Habituellement, vous pouvez faire ce que vous avez besoin avec booléenne simple indexation.

72
répondu Joe Kington 2011-04-12 22:48:27

Vieille Réponse c'est un peu déroutant. Il vous donne les endroits (tous) où votre statment est vrai.

:

>>> a = np.arange(100)
>>> np.where(a > 30)
(array([31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
       48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
       65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
       82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
       99]),)
>>> np.where(a == 90)
(array([90]),)

a = a*40
>>> np.where(a > 1000)
(array([26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
       43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
       60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
       77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
       94, 95, 96, 97, 98, 99]),)
>>> a[25]
1000
>>> a[26]
1040

je l'utilise comme une alternative à la liste.index(), mais il a de nombreux autres usages. Je ne l'ai jamais utilisé avec des tableaux 2D.

http://docs.scipy.org/doc/numpy/reference/generated/numpy.where.html

Nouvelle Réponse Il semble que la personne demandait quelque chose de plus fondamental.

la question était de savoir comment mettre en œuvre quelque chose qui permet à une fonction (comme où) de savoir ce qui a été demandé.

tout d'abord noter que l'appel à l'un des opérateurs de comparaison fait une chose intéressante.

a > 1000
array([False, False, False, False, False, False, False, False, False,
       False, 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,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True`,  True,  True,  True,  True,  True,  True,  True,  True,  True], dtype=bool)`

ceci est fait en surchargeant la méthode" __gt__". Par exemple:

>>> class demo(object):
    def __gt__(self, item):
        print item


>>> a = demo()
>>> a > 4
4

comme vous pouvez le voir," a > 4 " était un code valide.

vous pouvez obtenir une liste complète et la documentation de toutes les fonctions surchargées ici: http://docs.python.org/reference/datamodel.html

ce qui est incroyable, c'est à quel point c'est simple de faire ça. Toutes les opérations en python sont faites de cette manière. Dire A > b est équivalent à A. gt (b)!

21
répondu Garrett Berg 2011-04-12 23:13:03

np.where renvoie un tuple de longueur égale à la dimension du numpy ndarray sur lequel il est appelé (en d'autres termes ndim ) et chaque item de tuple est un numpy ndarray d'indices de toutes ces valeurs dans le ndarray initial pour lequel la condition est vraie. (Merci de ne pas confondre la dimension de la forme)

par exemple:

x=np.arange(9).reshape(3,3)
print(x)
array([[0, 1, 2],
      [3, 4, 5],
      [6, 7, 8]])
y = np.where(x>4)
print(y)
array([1, 2, 2, 2], dtype=int64), array([2, 0, 1, 2], dtype=int64))



y est un tuple de longueur 2 parce que x.ndim est 2. Le premier élément de tuple contient les numéros de ligne de tous les éléments supérieurs à 4 et le deuxième élément contient les numéros de colonne de tous les éléments supérieurs à 4. Comme vous pouvez le voir, [1,2,2,2] correspond à des numéros de ligne de 5,6,7,8 et [2,0,1,2] correspond à des numéros de colonne de 5,6,7,8 Notez que le ndarray est traversé le long de la première dimension(en ligne).

de même,

x=np.arange(27).reshape(3,3,3)
np.where(x>4)



sera de retour un tuple de longueur 3 parce que x a 3 dimensions.

mais attendez, il y a plus à np.où les!

lorsque deux arguments supplémentaires sont ajoutés à np.where ; il remplacera toutes les combinaisons ligne-colonne obtenues par le tuple ci-dessus.

x=np.arange(9).reshape(3,3)
y = np.where(x>4, 1, 0)
print(y)
array([[0, 0, 0],
   [0, 0, 1],
   [1, 1, 1]])
0
répondu Piyush Singh 2018-03-28 21:44:45