Самый быстрый способ создания массива 2D numpy, элементы которого находятся в диапазоне

Я хочу создать массив 2D numpy, где я хочу сохранить координаты пикселей, так что массив numpy выглядит следующим образом

[(0, 0), (0, 1), (0, 2), ...., (0, 510), (0, 511)
 (1, 0), (1, 1), (1, 2), ...., (1, 510), (1, 511)
 ..
 ..
 ..
 (511, 0), (511, 1), (511, 2), ...., (511, 510), (511, 511)]

Это смешной вопрос, но я еще ничего не нашел.

Ответ 1

Можно использовать np.indices или np.meshgrid для более продвинутого индексации:

>>> data=np.indices((512,512)).swapaxes(0,2).swapaxes(0,1)
>>> data.shape
(512, 512, 2)

>>> data[5,0]
array([5, 0])
>>> data[5,25]
array([ 5, 25])

Это может показаться странным, потому что он действительно сделал что-то вроде этого:

>>> a=np.ones((3,3))
>>> ind=np.indices((2,1))
>>> a[ind[0],ind[1]]=0
>>> a
array([[ 0.,  1.,  1.],
       [ 0.,  1.,  1.],
       [ 1.,  1.,  1.]])

A mgrid пример:

np.mgrid[0:512,0:512].swapaxes(0,2).swapaxes(0,1)

Пример meshgrid:

>>> a=np.arange(0,512)
>>> x,y=np.meshgrid(a,a)
>>> ind=np.dstack((y,x))
>>> ind.shape
(512, 512, 2)

>>> ind[5,0]
array([5, 0])

Все эквивалентные способы сделать это; однако meshgrid можно использовать для создания неравномерных сеток.

Если вы не возражаете переключать индексы строк и столбцов, вы можете удалить окончательный swapaxes(0,1).

Ответ 2

Пример в вопросе не совсем понятен - лишние запятые отсутствуют или добавлены дополнительные символы.

Этот пример - пример диапазонов 3, 4 для ясности - предоставляет решение для первого варианта и создает действующий 2D-массив (как следует из названия вопроса) - "перечисление" всех координат:

>>> np.indices((3,4)).reshape(2,-1).T
array([[0, 0],
       [0, 1],
       [0, 2],
       [0, 3],
       [1, 0],
       [1, 1],
       [1, 2],
       [1, 3],
       [2, 0],
       [2, 1],
       [2, 2],
       [2, 3]])

Другой вариант уже был показан в другом ответе, используя 2x .swapaxes() - но это также можно сделать с помощью одного np.rollaxis() (или нового np.moveaxis()):

>>> np.rollaxis(np.indices((3,4)), 0, 2+1)
array([[[0, 0],
        [0, 1],
        [0, 2],
        [0, 3]],

       [[1, 0],
        [1, 1],
        [1, 2],
        [1, 3]],

       [[2, 0],
        [2, 1],
        [2, 2],
        [2, 3]]])
>>> _[0,1]
array([0, 1])

Этот метод также работает одинаково для N-мерных индексов, например:

>>> np.rollaxis(np.indices((5,6,7)), 0, 3+1)

Примечание. Функция np.indices работает действительно (скорость C) быстро для больших диапазонов.

Ответ 3

Здесь вы можете использовать np.ogrid. Вместо сохранения tuple сохраните его в трехмерном массиве.

>>> t_row, t_col = np.ogrid[0:512, 0:512]
>>> a = np.zeros((512, 512, 2), dtype=np.uint8)
>>> t_row, t_col = np.ogrid[0:512, 0:512]
>>> a[t_row, t_col, 0] = t_row
>>> a[t_row, t_col, 1] = t_col

Это должно сделать трюк. Надеюсь, вы можете использовать это вместо кортежа.

Chintak