条件を満たした場合にNumpyの要素を置き換える

大きなnumpy配列があり、ある条件を満たすと各要素が1か0になるように操作する必要があります(後でピクセルマスクとして使用する予定です)。配列には約800万個の要素があり、現在の方法では縮小パイプラインの処理に時間がかかりすぎてしまいます。

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

これを高速化するnumpy関数はないのでしょうか?

質問へのコメント (2)
ソリューション
>>> 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]])

で短縮することができます。

>>> c = (a < 3).astype(int)
解説 (1)
>>> 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]])
>>>

例えば、boolean配列によるインデックス作成を参照してください。

解説 (3)

最も速い(そして最も柔軟な)方法は[np.where][1]を使用することです。これは、マスク(真値と偽値の配列)に従って2つの配列から選択します。


import numpy as np
a = np.random.randint(0, 5, size=(5, 4))
b = np.where(a
解説 (0)

次のように、マスク配列を一度に作成することができます。

mask_data = input_mask_data < 3

これにより、ピクセルマスクとして使用できるブール値の配列が作成されます。入力配列は変更せず、マスクデータを格納するために新しい配列を作成していることに注意してください。

>>> 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)
>>> 
解説 (1)

私はあなたの質問を理解したかどうかはわかりませんが、あなたが書いた場合:

mask_data[:3, :3] = 1
mask_data[3:, 3:] = 0

これにより、xインデックスとyインデックスが3未満のマスクデータのすべての値が1に等しくなり、残りのすべてが0になります。

解説 (0)