Tengo una matriz 2D NumPy y me gustaría reemplazar todos los valores en ella mayores o iguales a un umbral T con 255.0. Que yo sepa, la forma más fundamental sería:
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
¿Cuál es la forma más concisa y pitónica de hacer esto?
¿Hay una manera más rápida (posiblemente menos concisa y / o menos pitónica) de hacer esto?
Esto formará parte de una subrutina de ajuste de ventana / nivel para imágenes de resonancia magnética de la cabeza humana. La matriz numpy 2D son los datos de píxeles de la imagen.

Respuestas:
Creo que la forma más rápida y concisa de hacer esto es usar la indexación Fancy incorporada de NumPy. Si tiene un
ndarraynombrearr, puede reemplazar todos los elementos>255con un valor de laxsiguiente manera:Ejecuté esto en mi máquina con una matriz aleatoria de 500 x 500, reemplazando todos los valores> 0.5 con 5, y tomó un promedio de 7.59ms.
fuente
arr, en lugar de crear unaresultmatriz como en el OP.Asino creando una nueva matriz?np.array([1,2,3])Dado que realmente desea una matriz diferente que es
arrdondearr < 255, y de lo255contrario, esto puede hacerse simplemente:Más generalmente, para un límite inferior y / o superior:
Si solo desea acceder a los valores superiores a 255, o algo más complicado, la respuesta de @ mtitan8 es más general, pero
np.clipynp.minimum(onp.maximum) son más agradables y más rápidos para su caso:Si desea hacerlo en el lugar (es decir, modificar en
arrlugar de crearresult) puede usar eloutparámetro denp.minimum:o
(el
out=nombre es opcional ya que los argumentos están en el mismo orden que la definición de la función).Para la modificación en el lugar, la indexación booleana se acelera mucho (sin tener que hacer y luego modificar la copia por separado), pero aún no es tan rápido como
minimum:A modo de comparación, si quisiera restringir sus valores con un mínimo y un máximo, sin
cliptener que hacer esto dos veces, con algo comoo,
fuente
a[start:stop:step]le da los elementos de la matriz desdestarthastastop, pero en lugar de cada elemento, solo toma cada unostep(si se descuida, es1por defecto ) Por lo tanto, para poner todos los pares a cero, podría hacerloa[::2] = 0Creo que puedes lograr esto más rápido usando la
wherefunción:Por ejemplo, buscar elementos mayores que 0.2 en una matriz numpy y reemplazar aquellos con 0:
fuente
Puede considerar usar numpy.putmask :
Aquí hay una comparación de rendimiento con la indexación integrada de Numpy:
fuente
Otra forma es usar el
np.placeque reemplaza en el lugar y funciona con matrices multidimensionales:fuente
np.placetambién fue más lento en comparación con el método incorporado, aunque se afirma lo contrario en este comentario.También puede usar
&,|(y / o) para obtener más flexibilidad:valores entre 5 y 10:
A[(A>5)&(A<10)]valores mayores que 10 o menores que 5:
A[(A<5)|(A>10)]fuente