Ich habe ein großes numpy-Array, das ich so bearbeiten muss, dass jedes Element in eine 1 oder 0 geändert wird, wenn eine Bedingung erfüllt ist (wird später als Pixelmaske verwendet). Das Array enthält etwa 8 Millionen Elemente, und meine derzeitige Methode dauert zu lange für die Reduktionspipeline:
for (y,x), value in numpy.ndenumerate(mask_data):
if mask_data[y,x]<3: #Good Pixel
mask_data[y,x]=1
Elif mask_data[y,x]>3: #Bad Pixel
mask_data[y,x]=0
Gibt es eine numpy-Funktion, die dies beschleunigen würde?
>>> import numpy as np
>>> a = np.random.randint(0, 5, size=(5, 4))
>>> a
array([[4, 2, 1, 1],
[3, 0, 1, 2],
[2, 0, 1, 1],
[4, 0, 2, 3],
[0, 0, 0, 2]])
>>> b = a < 3
>>> b
array([[False, True, True, True],
[False, True, True, True],
[ True, True, True, True],
[False, True, True, False],
[ True, True, True, True]], dtype=bool)
>>>
>>> c = b.astype(int)
>>> c
array([[0, 1, 1, 1],
[0, 1, 1, 1],
[1, 1, 1, 1],
[0, 1, 1, 0],
[1, 1, 1, 1]])
Sie können dies mit abkürzen:
>>> c = (a < 3).astype(int)
>>> a = np.random.randint(0, 5, size=(5, 4))
>>> a
array([[0, 3, 3, 2],
[4, 1, 1, 2],
[3, 4, 2, 4],
[2, 4, 3, 0],
[1, 2, 3, 4]])
>>>
>>> a[a > 3] = -101
>>> a
array([[ 0, 3, 3, 2],
[-101, 1, 1, 2],
[ 3, -101, 2, -101],
[ 2, -101, 3, 0],
[ 1, 2, 3, -101]])
>>>
Siehe zB Indexierung mit booleschen Arrays .
Der schnellste (und flexibelste) Weg besteht in der Verwendung von np.where , wobei je nach Maske zwischen zwei Arrays (Array mit den Werten true und false) gewählt wird:
import numpy as np
a = np.random.randint(0, 5, size=(5, 4))
b = np.where(a<3,0,1)
print('a:',a)
print()
print('b:',b)
was wird produzieren:
a: [[1 4 0 1]
[1 3 2 4]
[1 0 2 1]
[3 1 0 0]
[1 4 0 1]]
b: [[0 1 0 0]
[0 1 0 1]
[0 0 0 0]
[1 0 0 0]
[0 1 0 0]]
Sie können so Ihr Masken-Array in einem Schritt erstellen
mask_data = input_mask_data < 3
Dadurch wird ein boolesches Array erstellt, das dann als Pixelmaske verwendet werden kann. Beachten Sie, dass wir das Eingabearray nicht geändert haben (wie in Ihrem Code), sondern ein neues Array für die Maskendaten erstellt haben - ich würde empfehlen, dies auf diese Weise zu tun.
>>> input_mask_data = np.random.randint(0, 5, (3, 4))
>>> input_mask_data
array([[1, 3, 4, 0],
[4, 1, 2, 2],
[1, 2, 3, 0]])
>>> mask_data = input_mask_data < 3
>>> mask_data
array([[ True, False, False, True],
[False, True, True, True],
[ True, True, False, True]], dtype=bool)
>>>
Ich bin nicht sicher, ob ich deine Frage verstanden habe, aber wenn du schreibst:
mask_data[:3, :3] = 1
mask_data[3:, 3:] = 0
Dadurch werden alle Werte von Maskendaten, deren x- und y-Indizes kleiner als 3 sind, gleich 1 und alle übrigen gleich 0