Sustitución de elementos Numpy si se cumple una condición

Tengo una gran matriz numpy que necesito manipular para que cada elemento se cambie a 1 o 0 si se cumple una condición (se utilizará como una máscara de píxeles más tarde). Hay alrededor de 8 millones de elementos en la matriz y mi método actual toma demasiado tiempo para la tubería de reducción:

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

¿Hay alguna función numpy que pueda acelerar este proceso?

Solución
>>> 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]])

Puede acortar esto con:

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

Véase, por ejemplo, Indexación con matrices booleanas.

Comentarios (3)

Puede crear su matriz de máscaras en un solo paso de la siguiente manera

mask_data = input_mask_data < 3

Esto crea una matriz booleana que puede ser utilizada como máscara de píxeles. Tenga en cuenta que no hemos cambiado la matriz de entrada (como en su código), sino que hemos creado una nueva matriz para contener los datos de la máscara - Yo recomendaría hacerlo de esta manera.

>>> 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)
>>> 
Comentarios (1)