Обернуть 2D-координаты массива numpy

У меня есть (5, 5) 2D-массив Numpy:

map_height = 5
map_width = 5

# Define a 2D np array-
a = np.arange(map_height * map_width).reshape(map_height, map_width)

# a
'''
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])
'''

Я могу обернуть этот массив по обеим осям, используя «pad()»:

a_wrapped = np.pad(array = a, pad_width = 1, mode = 'wrap')

a_wrapped
'''
array([[24, 20, 21, 22, 23, 24, 20],
       [ 4,  0,  1,  2,  3,  4,  0],
       [ 9,  5,  6,  7,  8,  9,  5],
       [14, 10, 11, 12, 13, 14, 10],
       [19, 15, 16, 17, 18, 19, 15],
       [24, 20, 21, 22, 23, 24, 20],
       [ 4,  0,  1,  2,  3,  4,  0]])
'''

Двумерные координаты (5, 5) «a» вычисляются (неэффективно) как:

# 2D coordinates -
# 1st channel/axis = row indices & 2 channel/axis = column indices.
a_2d_coords = np.zeros((map_height, map_width, 2), dtype = np.int16)

for row_idx in range(map_height):
    for col_idx in range(map_width):
        a_2d_coords[row_idx, col_idx][0] = row_idx
        a_2d_coords[row_idx, col_idx][1] = col_idx


# a_2d_coords.shape
# (5, 5, 2)

Я также хочу обернуть этот массив 2D-координат «a_2d_coords», выполнив:

a_2d_coords_wrapped = np.pad(array = a_2d_coords, pad_width = 1, mode = 'wrap')

# a_2d_coords_wrapped.shape
# (7, 7, 4)

Он также оборачивает третью ось/измерение, чего делать не следует! Цель состоит в том, чтобы координаты a[1, 4] = (1, 4) и координаты его соседа справа (RHS) были a[1, 0] = (1, 0). Это обтекание оси X. Аналогично, 2D-координаты оси Y также должны быть перенесены.

Мне не очень понятно, чего вы ожидаете в результате. Не могли бы вы добавить пример для этой части? Какова окончательная форма?

Shaido 18.06.2024 11:12
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
96
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Прежде всего, вы можете упростить расчет 2D-координат следующим образом:

a_2d_coords = np.moveaxis(np.mgrid[:map_height, :map_width], 0, -1)

Давайте проверим, дает ли это тот же результат:

import numpy as np

# For the check, use different height and width values to detect swaps
map_height, map_width = 3, 7

# Original implementation for coords
a_2d_coords_given = np.zeros((map_height, map_width, 2), dtype = np.int16)

for row_idx in range(map_height):
    for col_idx in range(map_width):
        a_2d_coords_given[row_idx, col_idx][0] = row_idx
        a_2d_coords_given[row_idx, col_idx][1] = col_idx

# Proposed implementation for coords
a_2d_coords = np.moveaxis(np.mgrid[:map_height, :map_width], 0, -1)
# Equality check
assert np.all(a_2d_coords == a_2d_coords_given)

Во-вторых, если вы заметите, что аргумент pad_widthnp.pad также может принимать значения, специфичные для оси, то вы можете добиться желаемого заполнения координат следующим образом:

a_2d_coords_wrapped = np.pad(a_2d_coords, mode = "wrap",
                             pad_width=((1, 1), (1, 1), (0, 0)))

Теперь мы дополняем ось 0 и ось 1 одним ведущим и одним конечным значением ((1, 1)), но оставляем ось 2 в покое ((0, 0)).

Итого имеем:

import numpy as np

map_height, map_width = 5, 5
a = np.arange(map_height * map_width).reshape(map_height, map_width)

a_2d_coords = np.moveaxis(np.mgrid[:map_height, :map_width], 0, -1)

a_2d_coords_wrapped = np.pad(a_2d_coords, mode = "wrap",
                             pad_width=((1, 1), (1, 1), (0, 0)))
print(a[a_2d_coords_wrapped[..., 0], a_2d_coords_wrapped[..., 1]])
# Prints
# [[24 20 21 22 23 24 20]
#  [ 4  0  1  2  3  4  0]
#  [ 9  5  6  7  8  9  5]
#  [14 10 11 12 13 14 10]
#  [19 15 16 17 18 19 15]
#  [24 20 21 22 23 24 20]
#  [ 4  0  1  2  3  4  0]]

Дальнейшее упрощение

Мы можем упростить код еще на один шаг, предоставив a_2d_coords/a_2d_coords_wrapped как массив 2×В×Ш, а не массив В×Ш×2:

import numpy as np

map_height, map_width = 5, 5
a = np.arange(map_height * map_width).reshape(map_height, map_width)

a_2d_coords = np.mgrid[:map_height, :map_width]

a_2d_coords_wrapped = np.pad(a_2d_coords, mode = "wrap",
                             pad_width=((0, 0), (1, 1), (1, 1)))
print(a[*a_2d_coords_wrapped])
# Prints
# [[24 20 21 22 23 24 20]
#  [ 4  0  1  2  3  4  0]
#  [ 9  5  6  7  8  9  5]
#  [14 10 11 12 13 14 10]
#  [19 15 16 17 18 19 15]
#  [24 20 21 22 23 24 20]
#  [ 4  0  1  2  3  4  0]]

Обратите внимание на * в a[*a_2d_coords_wrapped], который необходим для «распаковки» координат, чтобы для индексации предоставлялись два массива H×W, а не один массив 2×H×W.

a[*a_2d_coords_wrapped] выдает ошибку: a[*a_2d_coords_wrapped] — SyntaxError: неверный синтаксис
Arun 19.06.2024 11:35

@Arun (1) Какую версию Python вы используете? Используемый синтаксис, возможно, работает только для более поздних версий Python. (2) Вместо этого в любом случае должно работать следующее: a[a_2d_coords_wrapped[0], a_2d_coords_wrapped[1]]

simon 19.06.2024 12:00

Другие вопросы по теме