Как разделить 2D матрицу на патчи и умножить каждый патч на его центральный элемент? - PullRequest
1 голос
/ 22 февраля 2020

Мне нужно разделить 2D-матрицу на набор 2D-патчей с определенным шагом, затем умножить каждый патч на его центральный элемент и суммировать элементы каждого патча.

Это похоже на свертку, где для каждого элемента матрицы используется отдельное ядро.

Ниже приведена наглядная иллюстрация. Элементы матрицы результатов рассчитываются следующим образом:

Element 1 Element 2 Element 3

Element 4 Element 5

Результат должен выглядеть следующим образом:

Result

Вот решение, которое я придумала:

window_shape = (2, 2)
stride = 1

# Matrix
m = np.arange(1, 17).reshape((4, 4))

# Pad it once per axis to make sure the number of views
# equals the number of elements
m_padded = np.pad(m, (0, 1))

# This function divides the array into `windows`, from:
# https://stackoverflow.com/questions/45960192/using-numpy-as-strided-function-to-create-patches-tiles-rolling-or-sliding-w#45960193
w = window_nd(m_padded, window_shape, stride)
ww, wh, *_ = w.shape
w = w.reshape((ww * wh, 4))  # Two first dimensions multiplied is the number of rows

# Tile each center element for element-wise multiplication
m_tiled = np.tile(m.ravel(), (4, 1)).transpose()

result = (w * m_tiled).sum(axis = 1).reshape(m.shape)

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

Что лучше или эффективнее способ сделать это? 1039 * это?

1 Ответ

2 голосов
/ 22 февраля 2020

Попробуйте scipy.signal.convolve

from scipy.signal import convolve

window_shape = (2, 2)
stride = 1

# Matrix
m = np.arange(1, 17).reshape((4, 4))

# Pad it once per axis to make sure the number of views
# equals the number of elements
m_padded = np.pad(m, (0, 1))

output = convolve(m_padded, np.ones(window_shape), 'valid') * m
print(output)

Выход:

array([[ 14.,  36.,  66.,  48.],
       [150., 204., 266., 160.],
       [414., 500., 594., 336.],
       [351., 406., 465., 256.]])
...