arrays - significa - ¿Hay alguna forma conveniente de aplicar una tabla de búsqueda a una matriz grande en números?
que es un array en c++ (2)
La respuesta de TheodrosZelleke es correcta, pero solo quería agregarle un poco de sabiduría indocumentada. Numpy proporciona una función, np.take
, que según la documentación "hace lo mismo que la indexación elegante".
Bueno, casi, pero no exactamente lo mismo:
>>> import numpy as np
>>> lut = np.arange(256)
>>> image = np.random.randint(256, size=(5000, 5000))
>>> np.all(lut[image] == np.take(lut, image))
True
>>> import timeit
>>> timeit.timeit(''lut[image]'',
... ''from __main__ import lut, image'', number=10)
4.369504285407089
>>> timeit.timeit(''np.take(lut, image)'',
... ''from __main__ import np, lut, image'', number=10)
1.3678052776554637
np.take
es aproximadamente 3 veces más rápido! En mi experiencia, al usar luts 3D para convertir imágenes de RGB a otros espacios de color, agregar lógica para convertir la búsqueda 3D en una búsqueda aplanada 1D permite una aceleración de x10.
Tengo una imagen leída en números con unos pocos píxeles en mi matriz resultante.
Calculé una tabla de búsqueda con 256 valores. Ahora quiero hacer lo siguiente:
for i in image.rows:
for j in image.cols:
mapped_image[i,j] = lut[image[i,j]]
Sí, eso es básicamente lo que hace un lut.
El único problema es: quiero hacerlo de manera eficiente y llamar a ese bucle en Python me hará esperar algunos segundos para que termine.
Sé de numpy.vectorize()
, es simplemente una función de conveniencia que llama al mismo código de Python.
Puede usar la image
para indexar en lut
si lut
es 1D .
Aquí hay un motor de arranque en indexación en NumPy:
http://www.scipy.org/Tentative_NumPy_Tutorial#head-864862d3f2bb4c32f04260fac61eb4ef34788c4c
In [54]: lut = np.arange(10) * 10
In [55]: img = np.random.randint(0,9,size=(3,3))
In [56]: lut
Out[56]: array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
In [57]: img
Out[57]:
array([[2, 2, 4],
[1, 3, 0],
[4, 3, 1]])
In [58]: lut[img]
Out[58]:
array([[20, 20, 40],
[10, 30, 0],
[40, 30, 10]])
Cuidado también la indexación comienza en 0