wake-up-neo.net

Numpy-Elemente ersetzen, wenn die Bedingung erfüllt ist

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?

48
ChrisFro
>>> 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)
76
Steve Barnes
>>> 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

52
ev-br

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]]
22
Markus Dutschke

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)
>>> 
3
YXD

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

0
mamalos