Ich habe ein 2D-NumPy-Array und möchte alle darin enthaltenen Werte, die größer oder gleich einem Schwellenwert T sind, durch 255,0 ersetzen. Meines Wissens wäre der grundlegendste Weg:
shape = arr.shape
result = np.zeros(shape)
for x in range(0, shape[0]):
for y in range(0, shape[1]):
if arr[x, y] >= T:
result[x, y] = 255
Was ist der prägnanteste und pythonischste Weg, dies zu tun?
Gibt es eine schnellere (möglicherweise weniger prägnante und / oder weniger pythonische) Möglichkeit, dies zu tun?
Dies ist Teil einer Unterroutine zur Fenster- / Pegelanpassung für MRT-Scans des menschlichen Kopfes. Das 2D-Numpy-Array sind die Bildpixeldaten.
Antworten:
Ich denke, der schnellste und prägnanteste Weg, dies zu tun, ist die Verwendung der integrierten Fancy-Indizierung von NumPy. Wenn Sie einen
ndarray
Namen habenarr
, können Sie alle Elemente wie folgt>255
durch einen Wert ersetzenx
:Ich habe dies auf meinem Computer mit einer Zufallsmatrix von 500 x 500 ausgeführt, wobei alle Werte> 0,5 durch 5 ersetzt wurden, und es dauerte durchschnittlich 7,59 ms.
quelle
arr
, anstattresult
wie im OP ein Array zu erstellen .A
sondern ein neues Array erstellen?np.array([1,2,3]
) befindenDa Sie tatsächlich ein anderes Array wünschen,
arr
woarr < 255
und255
ansonsten, kann dies einfach durchgeführt werden:Allgemeiner für eine Unter- und / oder Obergrenze:
Wenn Sie nur auf Werte über 255 oder etwas Komplizierteres zugreifen möchten, ist die Antwort von @ mtitan8 allgemeiner, aber
np.clip
undnp.minimum
(odernp.maximum
) sind für Ihren Fall schöner und viel schneller:Wenn Sie dies direkt tun möchten (dh ändern
arr
statt erstellenresult
), können Sie den folgendenout
Parameter verwendennp.minimum
:oder
(Der
out=
Name ist optional, da die Argumente in derselben Reihenfolge wie die Definition der Funktion vorliegen.)Bei direkten Änderungen beschleunigt sich die boolesche Indizierung erheblich (ohne dass die Kopie separat erstellt und anschließend geändert werden muss), ist jedoch immer noch nicht so schnell wie
minimum
:Zum Vergleich, wenn Sie Ihre Werte sowohl auf ein Minimum als auch auf ein Maximum beschränken
clip
möchten , ohne dass Sie dies zweimal tun müssten, mit so etwas wieoder,
quelle
a[start:stop:step]
Gibt Ihnen die Elemente des Arrays vonstart
bis anstop
, aber anstelle jedes Elements werden nur alle Elemente verwendetstep
(wenn dies vernachlässigt wird, ist dies1
standardmäßig der Fall) ). Also, um alle Ereignisse auf Null zu setzen, könnten Sie tuna[::2] = 0
Ich denke, Sie können dies am schnellsten erreichen, indem Sie die
where
Funktion verwenden:Suchen Sie beispielsweise nach Elementen mit mehr als 0,2 in einem numpy-Array und ersetzen Sie diese durch 0:
quelle
Sie können die Verwendung von numpy.putmask in Betracht ziehen :
Hier ist ein Leistungsvergleich mit der integrierten Indexierung des Numpy:
quelle
Eine andere Möglichkeit ist die Verwendung,
np.place
die direkt vor Ort ersetzt wird und mit multidimentionalen Arrays funktioniert:quelle
np.place
war es auch langsamer als bei der eingebauten Methode, obwohl in diesem Kommentar das Gegenteil behauptet wird .Sie können auch verwendet werden
&
,|
(und / oder) für mehr Flexibilität:Werte zwischen 5 und 10:
A[(A>5)&(A<10)]
Werte größer als 10 oder kleiner als 5:
A[(A<5)|(A>10)]
quelle