Numpy.where verstehen
Ich möchte den ersten Index des numpy-Array-Elements erhalten, der größer ist als ein bestimmtes Element desselben Arrays. Ich habe Folgendes versucht:
>>> 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. Ist oben der richtige Weg, um den ersten Index eines Elements Q5[0]größer als zu erhalten Q5[0,0]?
Ich bin mehr darum bemüht np.where(Q5[0]>Q5[0,0]), Tupel zurückzugeben, (array([1, 2], dtype=int32),)und fordere mich daher auf, den Index [0][0]am Ende von zu verdoppeln np.where(Q5[0]>Q5[0,0])[0][0].
Q2. Warum gibt dieses Rückgabetupel, aber unten das richtige Numpy-Array zurück?
>>> np.where(Q5[0]>Q5[0,0],Q5[0],-1)
array([-1, 2, 3])
Damit ich direkt indizieren kann:
>>> np.where(Q5[0]>Q5[0,0],Q5[0],-1)[1]
2
Antworten
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.wheremit nur der Bedingung ist wirklich np.nonzero.
Generieren Sie ein boolesches Array:
In [63]: A==6
Out[63]:
array([[False, False, False],
[False, False, True],
[False, False, False]])
Finden Sie heraus, wo das stimmt:
In [64]: np.nonzero(A==6)
Out[64]: (array([1]), array([2]))
Das Ergebnis ist ein Tupel, ein Element pro Dimension der Bedingung. Jedes Element ist ein Indizierungsarray. Zusammen definieren sie die Position der True (s).
Ein weiterer Test mit mehreren 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]))
Verwenden des Tupels zum Indizieren des ursprünglichen Arrays:
In [67]: A[np.nonzero((A%3)==1)]
Out[67]: array([1, 4, 7])
Verwenden Sie das Argument 3 where, um ein neues Array mit einer Mischung von Werten aus Aund zu erstellenA+10
In [68]: np.where((A%3)==1,A+10, A)
Out[68]:
array([[11, 2, 3],
[14, 5, 6],
[17, 8, 9]])
Wenn die Bedingung mehrere True hat, nonzeroist dies nicht das Testwerkzeug zum Finden des "Ersten", da es notwendigerweise alle findet.
Das Tupel ungleich Null kann mit einem in ein 2D-Array umgewandelt werden transpose. Es kann tatsächlich einfacher sein, das "Erste" aus diesem Array zu erhalten:
In [73]: np.argwhere((A%3)==1)
Out[73]:
array([[0, 0],
[1, 0],
[2, 0]])
Sie suchen in einem 1d-Array, einer Reihe von 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])
Unabhängig davon, ob Sie ein 1d-Array oder ein 2d-Array (oder 3 oder 4) suchen, wird nonzeroein Tupel mit einem Array-Element pro Dimension zurückgegeben. Auf diese Weise kann es immer verwendet werden, um ein Array gleicher Größe zu indizieren. Das 1d-Tupel sieht möglicherweise redundant aus, stimmt jedoch mit anderen Dimensionsergebnissen überein.
Wenn Sie versuchen, solche Vorgänge zu verstehen, lesen Sie die Dokumente sorgfältig durch und sehen Sie sich die einzelnen Schritte an. Hier betrachte ich die bedingte Matrix, das nonzeroErgebnis und ihre verschiedenen Verwendungen.
numpy.where () ist wie eine for-Schleife mit einem if.
numpy.where(condition, values, new_value)
Bedingung - genau wie wenn Bedingungen.
values - Die Werte, die für
new_value iteriert werden sollen. Wenn die Bedingung für einen Wert erfüllt ist , wird sie in new_value geändert
Wenn wir es für ein eindimensionales Array schreiben möchten, sollte es ungefähr so aussehen:
[xv if c else yv
for c, xv, yv in zip(condition, x, y)]
Beispiel:
>>> 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])
Zuerst erstellen wir ein Array mit Zahlen von 0 bis 9 (0, 1, 2 ... 7, 8, 9)
und prüfen dann alle Werte im Array, die größer als 5 sind, und multiplizieren ihren Wert mit 10.
Jetzt sind alle Werte im Array, die kleiner als 5 sind, gleich geblieben und alle Werte, die größer sind, multipliziert mit 10
Wenn Sie argmaxein boolesches Array verwenden, erhalten Sie den Index des ersten 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 kann ein Achsen- / Dimensionsargument annehmen.
In [56]: np.argmax(q > q[0,0], 0)
Out[56]: array([1, 0, 0], dtype=int64)
Das heißt, das erste True ist Index eins für Spalte Null und Index Null für Spalte eins und zwei.
In [57]: np.argmax(q > q[0,0], 1)
Out[57]: array([1, 0], dtype=int64)
Das heißt, das erste True ist Index eins für Zeile Null und Index Null für Zeile eins.
Q1. Ist der obige richtige Weg, um den ersten Index eines Elements in Q5 [0] größer als Q5 [0,0] zu erhalten?
Nein, ich würde argmaxmit 1für das axisArgument verwenden und dann das erste Element aus diesem Ergebnis auswählen.
Q2. Warum dieses Rückgabetupel?
Sie haben ihm gesagt, dass er -1für falsche Werte und Q5[0]Elemente für wahre Werte zurückgeben soll.
Q2 ... aber unten wird das richtige Numpy-Array zurückgegeben?
Sie haben Glück gehabt und den richtigen Index gewählt.