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.
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.
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)!
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]])