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
ndarray
nombrearr
, puede reemplazar todos los elementos>255
con un valor de lax
siguiente 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 unaresult
matriz como en el OP.A
sino creando una nueva matriz?np.array([1,2,3]
)Dado que realmente desea una matriz diferente que es
arr
dondearr < 255
, y de lo255
contrario, 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.clip
ynp.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
arr
lugar de crearresult
) puede usar elout
pará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
clip
tener que hacer esto dos veces, con algo comoo,
fuente
a[start:stop:step]
le da los elementos de la matriz desdestart
hastastop
, pero en lugar de cada elemento, solo toma cada unostep
(si se descuida, es1
por defecto ) Por lo tanto, para poner todos los pares a cero, podría hacerloa[::2] = 0
Creo que puedes lograr esto más rápido usando la
where
funció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.place
que reemplaza en el lugar y funciona con matrices multidimensionales:fuente
np.place
tambié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