Zrozumieć numpy.where
Chcę uzyskać pierwszy indeks elementu tablicy numpy, który jest większy niż określony element tej samej tablicy. Próbowałem śledzić:
>>> 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. Czy powyższy sposób na uzyskanie pierwszego indeksu elementu w Q5[0]większym niż Q5[0,0]?
Bardziej interesuje mnie np.where(Q5[0]>Q5[0,0])zwracanie krotki (array([1, 2], dtype=int32),)i wymaganie ode mnie podwójnego indeksowania [0][0]na końcu np.where(Q5[0]>Q5[0,0])[0][0].
Q2. Dlaczego ta zwrotna krotka, ale poniżej zwraca właściwą tablicę numpy?
>>> np.where(Q5[0]>Q5[0,0],Q5[0],-1)
array([-1, 2, 3])
Aby móc bezpośrednio indeksować:
>>> np.where(Q5[0]>Q5[0,0],Q5[0],-1)[1]
2
Odpowiedzi
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.wheretylko warunek jest naprawdę np.nonzero.
Wygeneruj tablicę logiczną:
In [63]: A==6
Out[63]:
array([[False, False, False],
[False, False, True],
[False, False, False]])
Dowiedz się, gdzie to prawda:
In [64]: np.nonzero(A==6)
Out[64]: (array([1]), array([2]))
Wynikiem jest krotka, jeden element na wymiar warunku. Każdy element jest tablicą indeksującą, razem definiują lokalizację Prawdy (-ów)
Kolejny test z kilkoma 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]))
Używanie krotki do indeksowania oryginalnej tablicy:
In [67]: A[np.nonzero((A%3)==1)]
Out[67]: array([1, 4, 7])
Użycie argumentu 3 wheredo utworzenia nowej tablicy z kombinacją wartości z AiA+10
In [68]: np.where((A%3)==1,A+10, A)
Out[68]:
array([[11, 2, 3],
[14, 5, 6],
[17, 8, 9]])
Jeśli warunek ma wiele wartości Prawda, nonzeronie jest narzędziem testowym do znajdowania „pierwszego”, ponieważ koniecznie znajduje wszystkie.
Niezerową krotkę można przekształcić w tablicę 2d z rozszerzeniem transpose. W rzeczywistości może być łatwiej uzyskać „pierwszy” z tej tablicy:
In [73]: np.argwhere((A%3)==1)
Out[73]:
array([[0, 0],
[1, 0],
[2, 0]])
Szukasz w tablicy 1d, wiersz 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])
Więc niezależnie od tego, czy szukasz tablicy 1d, czy 2d (lub 3 lub 4), nonzerozwraca krotkę z jednym elementem tablicy na wymiar. W ten sposób zawsze można go użyć do indeksowania tablicy o podobnym rozmiarze. Krotka 1d może wyglądać na zbędną, ale jest zgodna z wynikami innych wymiarów.
Kiedy próbujesz zrozumieć takie operacje, przeczytaj uważnie dokumentację i przyjrzyj się poszczególnym krokom. Tutaj patrzę na macierz warunkową, nonzerowynik i jej różne zastosowania.
numpy.where () działa jak pętla for z if.
numpy.where(condition, values, new_value)
stan - tak jak warunki.
wartości - wartości do iteracji po
nowej_wartości - jeśli warunek jest prawdziwy dla wartości , zmieni się na nową_wartość
Jeśli chcielibyśmy napisać to dla 1-wymiarowej tablicy, powinno to wyglądać mniej więcej tak:
[xv if c else yv
for c, xv, yv in zip(condition, x, y)]
Przykład:
>>> 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])
Najpierw tworzymy tablicę z liczbami od 0 do 9 (0, 1, 2 ... 7, 8, 9),
a następnie sprawdzamy wszystkie wartości w tablicy, które są większe od 5 i mnożymy ich wartość przez 10.
Więc teraz wszystkie wartości w tablicy, które są mniejsze niż 5, pozostały takie same, a wszystkie wartości, które są większe, pomnożone przez 10
Używanie argmaxz tablicą boolowską daje indeks pierwszej wartości 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 może przyjąć argument osi / wymiaru.
In [56]: np.argmax(q > q[0,0], 0)
Out[56]: array([1, 0, 0], dtype=int64)
Oznacza to, że pierwsza prawda to indeks jeden dla kolumny zero i indeks zero dla kolumn pierwszej i drugiej.
In [57]: np.argmax(q > q[0,0], 1)
Out[57]: array([1, 0], dtype=int64)
Oznacza to, że pierwsza prawda to indeks jeden dla wiersza zerowego i indeks zero dla wiersza pierwszego.
Q1. Czy powyższy prawidłowy sposób uzyskania pierwszego indeksu elementu w Q5 [0] jest większy niż Q5 [0,0]?
Nie, użyłbym argmaxz 1jako axisargument, a następnie wybierz pierwszy element z tego wyniku.
Q2. Dlaczego ta zwrotna krotka
Powiedziałeś mu, aby -1zwracał wartości False i zwracał Q5[0]elementy dla wartości True.
Q2 ... ale poniżej zwraca właściwą tablicę numpy?
Masz szczęście i wybrałeś właściwy indeks.