W jaki sposób wewnętrznie osiągają, że jesteś w stanie przekazać metodę podobną do x> 5?
Krótka odpowiedź brzmi: tak nie jest.
Każda operacja logiczna na tablicy numpy zwraca tablicę logiczną. (to znaczy __gt__
, __lt__
itp wszystkie powrotne tablic logicznych, gdzie dany warunek jest spełniony).
Na przykład
x = np.arange(9).reshape(3,3)
print x > 5
plony:
array([[False, False, False],
[False, False, False],
[ True, True, True]], dtype=bool)
To jest ten sam powód, dla którego coś takiego jak if x > 5:
wywołuje ValueError, jeśli x
jest tablicą numpy. Jest to tablica wartości prawda / fałsz, a nie pojedyncza wartość.
Ponadto tablice numpy mogą być indeksowane przez tablice logiczne. Np. W tym przypadku x[x>5]
daje [6 7 8]
.
Szczerze mówiąc, jest to dość rzadkie, że faktycznie potrzebujesz, numpy.where
ale zwraca tylko wskazania, w których znajduje się tablica logiczna True
. Zwykle możesz zrobić to, czego potrzebujesz, dzięki prostemu indeksowaniu logicznemu.
numpy.where
mają 2 „tryby operacyjne”, pierwszy zwraca wartośćindices
, gdziecondition is True
i jeśli występują parametry opcjonalnex
iy
(taki sam kształtcondition
lub nadający się do nadawania do takiego kształtu!), Zwróci wartości z,x
gdy jestcondition is True
inaczejy
. Dzięki temu jestwhere
bardziej wszechstronny i umożliwia częstsze używanie. Dzięki__getitem__
składni[]
over albonumpy.where
lubnumpy.take
. Ponieważ__getitem__
musi również obsługiwać krojenie, jest trochę narzutu. Widziałem zauważalne różnice w szybkości podczas pracy ze strukturami danych Python Pandas i logicznym indeksowaniem bardzo dużych kolumn. W takich przypadkach, jeśli nie potrzebujesz krojenia, totake
iwhere
faktycznie są lepsze.Stara odpowiedź jest trochę zagmatwana. Daje ci LOKALIZACJE (wszystkie z nich), gdzie twoje stwierdzenie jest prawdziwe.
więc:
>>> 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
Używam go jako alternatywy dla list.index (), ale ma też wiele innych zastosowań. Nigdy nie używałem go z tablicami 2D.
http://docs.scipy.org/doc/numpy/reference/generated/numpy.where.html
Nowa odpowiedź Wydaje się, że osoba pytała o coś bardziej fundamentalnego.
Pytanie brzmiało, jak TY mógłbyś zaimplementować coś, co pozwala funkcji (na przykład gdzie) wiedzieć, czego zażądano.
Najpierw zwróć uwagę, że wywołanie dowolnego z operatorów porównania robi interesującą rzecz.
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)`
Odbywa się to poprzez przeciążenie metody „__gt__”. Na przykład:
>>> class demo(object): def __gt__(self, item): print item >>> a = demo() >>> a > 4 4
Jak widać, „a> 4” był prawidłowym kodem.
Możesz uzyskać pełną listę i dokumentację wszystkich przeciążonych funkcji tutaj: http://docs.python.org/reference/datamodel.html
Niesamowite jest to, jak łatwo to zrobić. WSZYSTKIE operacje w Pythonie są wykonywane w ten sposób. Powiedzenie a> b jest równoważne a. gt (b)!
źródło
np.where(a > 30 and a < 50)
lubnp.where(30 < a < 50)
ponieważ kończy się próbą obliczenia logicznego AND dwóch tablic logicznych, co jest dość bez znaczenia. Czy jest sposób, aby napisać taki stannp.where
?np.where((a > 30) & (a < 50))
np.where
zwraca krotkę o długości równej wymiarowi numpy ndarray, na której jest wywoływana (innymi słowyndim
), a każdy element krotki jest liczbą indeksów wszystkich tych wartości w początkowej tablicy ndarray, dla której warunek jest True. (Proszę nie mylić wymiaru z kształtem)Na przykład:
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 jest krotką o długości 2, ponieważ
x.ndim
wynosi 2. Pierwsza pozycja w krotce zawiera numery wierszy wszystkich elementów większych niż 4, a druga pozycja zawiera numery kolumn wszystkich elementów większych niż 4. Jak widać, [1,2,2 , 2] odpowiada numerom wierszy 5,6,7,8, a [2,0,1,2] odpowiada numerom kolumn 5,6,7,8 Zauważ, że ndarray przechodzi wzdłuż pierwszego wymiaru (w odniesieniu do wierszy ).Podobnie,
x=np.arange(27).reshape(3,3,3) np.where(x>4)
zwróci krotkę o długości 3, ponieważ x ma 3 wymiary.
Ale czekaj, jest więcej do np. Gdzie!
kiedy dodawane są dwa dodatkowe argumenty
np.where
; wykona operację zamiany dla wszystkich tych kombinacji wierszy i kolumn w parach, które są uzyskiwane przez powyższą krotkę.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]])
źródło