Есть ли удобный способ применить таблицу поиска к большому массиву в numpy? - программирование

Есть ли удобный способ применить таблицу поиска к большому массиву в numpy?

Ive получил изображение, читаемое в numpy с довольно большим количеством пикселей в моем результирующем массиве.

Я вычислил таблицу поиска с 256 значениями. Теперь я хочу сделать следующее:

for i in image.rows:
    for j in image.cols:
        mapped_image[i,j] = lut[image[i,j]]

Да, это в основном то, что делает lut.
Единственная проблема заключается в следующем: я хочу сделать это эффективным, и вызов этого цикла в python заставит меня ждать несколько секунд, чтобы он закончил.

Я знаю numpy.vectorize(), это просто удобная функция, которая вызывает тот же код python.

4b9b3361

Ответ 1

Вы можете просто использовать image для индексации в lut, если lut - 1D.
Здесь стартер по индексированию в 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]])

Обратите внимание, что индексирование начинается с 0

Ответ 2

TheodrosZelleke ответил правильно, но я просто хотел добавить к нему немного недокументированной мудрости. Numpy предоставляет функцию np.take, которая согласно документации "делает то же самое, что и причудливое индексирование".

Ну, почти, но не совсем то же самое:

>>> 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 примерно в 3 раза быстрее! По моему опыту, при использовании 3D-изображений для преобразования изображений из RGB в другие цветовые пространства добавление логики для преобразования 3D-вида в одномерный сплющенный поиск позволяет ускорить x10.