Ich weiß, es gibt eine Methode für eine Python-Liste, um den ersten Index von etwas zurückzugeben:
>>> l = [1, 2, 3]
>>> l.index(2)
1
Gibt es so etwas auch für NumPy-Arrays?
Ich weiß, es gibt eine Methode für eine Python-Liste, um den ersten Index von etwas zurückzugeben:
>>> l = [1, 2, 3]
>>> l.index(2)
1
Gibt es so etwas auch für NumPy-Arrays?
Ja, angesichts eines Arrays, array
und einen Wert, item
zu suchen, können Sie mit np.where
als:
itemindex = numpy.where(array == item)
Das Ergebnis ist ein Tupel, das zuerst alle Zeilenindizes und dann alle Spaltenindizes enthält.
Wenn ein Array zum Beispiel zwei Dimensionen hat und Ihr Element an zwei Stellen enthält, dann
array[itemindex[0][0]][itemindex[1][0]]
wäre gleich Ihrem Artikel und würde so sein:
array[itemindex[0][1]][itemindex[1][1]]
Wenn Sie den Index des ersten Vorkommens von nur ein Wert können Sie verwenden nonzero
(oder where
was in diesem Fall auf dasselbe hinausläuft):
>>> t = array([1, 1, 1, 2, 2, 3, 8, 3, 8, 8])
>>> nonzero(t == 8)
(array([6, 8, 9]),)
>>> nonzero(t == 8)[0][0]
6
Wenn Sie den ersten Index von jedem der viele Werte Sie könnten natürlich das Gleiche wie oben wiederholt tun, aber es gibt einen Trick, der vielleicht schneller ist. Im Folgenden werden die Indizes des ersten Elements der einzelnen Teilsequenz :
>>> nonzero(r_[1, diff(t)[:-1]])
(array([0, 3, 5, 6, 7, 8]),)
Beachten Sie, dass es den Anfang beider Teilfolgen von 3s und beider Teilfolgen von 8s findet:
[ 1 , 1, 1, 2 , 2, 3 , 8 , 3 , 8 , 8]
Es ist also etwas anders als die Suche nach der ersten Vorkommen eines jeden Wertes. In Ihrem Programm können Sie möglicherweise mit einer sortierten Version von t
um zu bekommen, was Sie wollen:
>>> st = sorted(t)
>>> nonzero(r_[1, diff(st)[:-1]])
(array([0, 3, 5, 7]),)
Nur um eine sehr leistungsfähige und praktische numba Alternative basierend auf np.ndenumerate
um den ersten Index zu finden:
from numba import njit
import numpy as np
@njit
def index(array, item):
for idx, val in np.ndenumerate(array):
if val == item:
return idx
# If no item was found return None, other return types might be a problem due to
# numbas type inference.
Das ist ziemlich schnell und geht natürlich mit mehrdimensionalen Arrays um :
>>> arr1 = np.ones((100, 100, 100))
>>> arr1[2, 2, 2] = 2
>>> index(arr1, 2)
(2, 2, 2)
>>> arr2 = np.ones(20)
>>> arr2[5] = 2
>>> index(arr2, 2)
(5,)
Dies kann sein wesentlich schneller (weil es den Vorgang kurzschließt) als jeder Ansatz, der np.where
o np.nonzero
.
Allerdings np.argwhere
könnte auch mit anmutig mit mehrdimensionalen Arrays (Sie müssten sie manuell in ein Tupel umwandeln) y er ist nicht kurzgeschlossen), aber er würde fehlschlagen, wenn keine Übereinstimmung gefunden wird:
>>> tuple(np.argwhere(arr1 == 2)[0])
(2, 2, 2)
>>> tuple(np.argwhere(arr2 == 2)[0])
(5,)
l.index(x)
gibt die kleinste i tal que i ist der Index des ersten Vorkommens von x in der Liste.
Man kann sicher davon ausgehen, dass die index()
Funktion in Python ist so implementiert, dass sie nach dem Finden der ersten Übereinstimmung anhält, was zu einer optimalen durchschnittlichen Leistung führt.
Um ein Element zu finden, das nach der ersten Übereinstimmung in einem NumPy-Array stehen bleibt, verwenden Sie einen Iterator ( ndenumerieren ).
In [67]: l=range(100)
In [68]: l.index(2)
Out[68]: 2
NumPy-Array:
In [69]: a = np.arange(100)
In [70]: next((idx for idx, val in np.ndenumerate(a) if val==2))
Out[70]: (2L,)
Beachten Sie, dass beide Methoden index()
et next
einen Fehler zurückgeben, wenn das Element nicht gefunden wird. Mit next
kann man ein zweites Argument verwenden, um einen speziellen Wert zurückzugeben, falls das Element nicht gefunden wird, z. B.
In [77]: next((idx for idx, val in np.ndenumerate(a) if val==400),None)
Es gibt weitere Funktionen in NumPy ( argmax
, where
y nonzero
), die verwendet werden können, um ein Element in einem Array zu finden, aber sie haben alle den Nachteil, dass sie das gesamte Array durchgehen und nach alle Vorkommen und ist somit nicht für das Auffinden des ersten Elements optimiert. Beachten Sie auch, dass where
et nonzero
geben Arrays zurück, so dass Sie das erste Element auswählen müssen, um den Index zu erhalten.
In [71]: np.argmax(a==2)
Out[71]: 2
In [72]: np.where(a==2)
Out[72]: (array([2], dtype=int64),)
In [73]: np.nonzero(a==2)
Out[73]: (array([2], dtype=int64),)
Ich überprüfe nur, dass die Lösung mit einem Iterator bei großen Arrays schneller ist wenn das gesuchte Element am Anfang des Arrays steht (mit %timeit
in der IPython-Shell):
In [285]: a = np.arange(100000)
In [286]: %timeit next((idx for idx, val in np.ndenumerate(a) if val==0))
100000 loops, best of 3: 17.6 µs per loop
In [287]: %timeit np.argmax(a==0)
1000 loops, best of 3: 254 µs per loop
In [288]: %timeit np.where(a==0)[0][0]
1000 loops, best of 3: 314 µs per loop
Dies ist eine offene NumPy GitHub Ausgabe .
Siehe auch: Numpy: den ersten Index eines Wertes schnell finden
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
5 Stimmen
ZU IHRER INFORMATION: Ermitteln der Indizes mehrerer Elemente in einem NumPy-Array auf einmal