Vraag Hoe werkt python numpy.where ()?


Ik speel met numpy en door documentatie te graven en ik ben wat magie tegengekomen. Namelijk waar ik het over heb numpy.where():

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

Hoe ze intern bereiken dat je zoiets kunt doorgeven x > 5 in een methode? Ik denk dat het iets te maken heeft met __gt__ maar ik ben op zoek naar een gedetailleerde uitleg.


87
2018-04-12 22:39


oorsprong


antwoorden:


Hoe bereiken ze intern dat je zoiets als x> 5 als een methode kunt gebruiken?

Het korte antwoord is dat ze dat niet doen.

Elke soort logische bewerking op een numpy array retourneert een booleaanse array. (d.w.z. __gt__, __lt__, enz. alle booleaanse arrays worden geretourneerd waar de gegeven voorwaarde waar is).

Bijv.

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

opbrengsten:

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

Dit is dezelfde reden waarom zoiets if x > 5: verhoogt een ValueError als x is een numpy array. Het is een reeks True / False-waarden, geen enkele waarde.

Bovendien kunnen numpy-arrays worden geïndexeerd door boolean-arrays. Bijv. x[x>5] opbrengsten [6 7 8], in dit geval.

Eerlijk gezegd is het vrij zeldzaam dat je het echt nodig hebt numpy.where maar het retourneert alleen de aanduidingen waar een booleaanse array is True. Meestal kun je doen wat je nodig hebt met eenvoudige booleaanse indexering.


71
2018-04-12 22:48



Oud antwoord het is nogal verwarrend. Het geeft je de LOCATIES (allemaal) van waar je verklaring geldig is.

zo:

>>> 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

Ik gebruik het als een alternatief voor list.index (), maar het heeft ook veel andere toepassingen. Ik heb het nog nooit gebruikt met 2D-arrays.

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

Nieuw antwoord Het lijkt erop dat de persoon iets fundamenteler vroeg.

De vraag was hoe je iets kon implementeren dat een functie (zoals waar) toelaat om te weten wat werd gevraagd.

Merk allereerst op dat het een interessante zaak is om een ​​van de vergelijkingsoperators te bellen.

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)`

Dit wordt gedaan door de "__gt__" -methode te overbelasten. Bijvoorbeeld:

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


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

Zoals u kunt zien, was "a> 4" een geldige code.

U kunt hier een volledige lijst en documentatie van alle overbelaste functies krijgen: http://docs.python.org/reference/datamodel.html

Iets dat ongelooflijk is, is hoe eenvoudig het is om dit te doen. ALLE bewerkingen in python worden op een dergelijke manier uitgevoerd. Het zeggen van a> b is gelijk aan a.gt(B)!


21
2018-04-12 22:45



np.where retourneert een tuple van lengte gelijk aan de dimensie van de numpy ndarray waarop deze wordt aangeroepen (met andere woorden ndim) en elk item van tuple is een numpy ndarray van indices van al die waarden in de initiële ndarray waarvoor de voorwaarde Waar is. (Verwar geen dimensie met vorm)

Bijvoorbeeld:

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 is een tuple van lengte 2 omdat x.ndim is 2. Het 1e item in tuple bevat rijnummers van alle elementen groter dan 4 en het tweede item bevat kolomnummers van alle items groter dan 4. Zoals u kunt zien, komt [1,2,2,2] overeen met rijnummers van 5,6,7,8 en [2,0,1,2] komen overeen met kolomnummers van 5,6,7,8 Merk op dat de ndarray langs de eerste dimensie wordt doorlopen (in rijen).

Evenzo

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


retourneert een tuple van lengte 3 omdat x drie dimensies heeft.

Maar wacht, er is meer aan np.where!

wanneer twee extra argumenten zijn toegevoegd aan np.where; het zal een vervangende bewerking uitvoeren voor al die paarsgewijze rij-kolomcombinaties die worden verkregen door het bovenstaande tupel.

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
2018-03-28 18:33