Самый быстрый способ создания массива 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