tutorial multiplicar matrices functions funciones español python arrays numpy replace condition

python - multiplicar - numpy functions



Reemplazar todos los elementos de Python NumPy Array que sean mayores que algún valor (6)

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

  1. ¿Cuál es la forma más concisa y pitónica de hacer esto?

  2. ¿Hay una manera más rápida (posiblemente menos conciso y / o menos pitónica) de hacer esto?

Esto será parte de una subrutina de ajuste de ventana / nivel para escaneos MRI de la cabeza humana. La matriz numpy 2D es la imagen de píxeles de imagen.


Como realmente quiere una matriz diferente que es arr donde arr < 255 y 255 contrario, esto se puede hacer simplemente:

result = np.minimum(arr, 255)

De manera más general, para un límite inferior y / o superior:

result = np.clip(arr, 0, 255)

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 y np.minimum (o np.maximum ) son más agradables y más rápidos para su caso:

In [292]: timeit np.minimum(a, 255) 100000 loops, best of 3: 19.6 µs per loop In [293]: %%timeit .....: c = np.copy(a) .....: c[a>255] = 255 .....: 10000 loops, best of 3: 86.6 µs per loop

Si desea hacerlo en el lugar (es decir, modificar arr lugar de crear result ) puede usar el parámetro out de np.minimum :

np.minimum(arr, 255, out=arr)

o

np.clip(arr, 0, 255, arr)

(el out= name es opcional ya que los argumentos están en el mismo orden que la definición de la función).

Para la modificación in situ, la indexación booleana se acelera mucho (sin tener que realizar y luego modificar la copia por separado), pero todavía no es tan rápida como minimum :

In [328]: %%timeit .....: a = np.random.randint(0, 300, (100,100)) .....: np.minimum(a, 255, a) .....: 100000 loops, best of 3: 303 µs per loop In [329]: %%timeit .....: a = np.random.randint(0, 300, (100,100)) .....: a[a>255] = 255 .....: 100000 loops, best of 3: 356 µs per loop

Para comparar, si quisiera restringir sus valores con un mínimo y un máximo, sin clip , tendría que hacer esto dos veces, con algo como

np.minimum(a, 255, a) np.maximum(a, 0, a)

o,

a[a>255] = 255 a[a<0] = 0


Creo que la forma más rápida y concisa de hacer esto es usar la indexación integrada de Numpy. Si tiene una ndarray llamada arr puede reemplazar todos los elementos >255 con un valor x siguiente manera:

arr[arr > 255] = x

Ejecuté esto en mi máquina con una matriz aleatoria de 500 x 500, reemplazando todos los valores> 0.5 por 5, y tardé un promedio de 7.59ms.

In [1]: import numpy as np In [2]: A = np.random.rand(500, 500) In [3]: timeit A[A > 0.5] = 5 100 loops, best of 3: 7.59 ms per loop


Creo que puedes lograr esto de la manera más rápida usando la función where :

Por ejemplo, busca elementos mayores a 0.2 en una matriz numpy y reemplaza aquellos con 0:

import numpy as np nums = np.random.rand(4,3) print np.where(nums > 0.2, 0, nums)


Otra forma es usar np.place que reemplaza y funciona con arreglos multidimensionales:

import numpy as np arr = np.arange(6).reshape(2, 3) np.place(arr, arr == 0, -10)


Puedes considerar usar numpy.putmask :

np.putmask(arr, arr>=T, 255.0)

Aquí hay una comparación de rendimiento con la indexación integrada de Numpy:

In [1]: import numpy as np In [2]: A = np.random.rand(500, 500) In [3]: timeit np.putmask(A, A>0.5, 5) 1000 loops, best of 3: 1.34 ms per loop In [4]: timeit A[A > 0.5] = 5 1000 loops, best of 3: 1.82 ms per loop


También puedes usar & , | (y / o) para 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)]