Быстрый способ вычисления матрицы из (Матрица - константа) - PullRequest
0 голосов
/ 05 мая 2020

Я хотел бы найти более быстрый способ вычисления матрицы v. Обратите внимание, что если высота = ширина, тогда матрица v является симметричной c, v = v.T. Ширина и высота - произвольные положительные целые числа.

v = np.zeros((height, width)) # rows columns

# region center
cr = np.round(height / 2)
cc = np.round(width / 2)

# there has to be a quicker way to do this
for w in range(width):
    v[:, w] = [np.sqrt((w - cc) ** 2 + (h - cr) ** 2) for h in range(height)]

Ответы [ 3 ]

1 голос
/ 05 мая 2020

Вы можете упростить это, используя numpy s broadcasting :

out = np.sqrt((np.arange(width)-cc)**2 + (np.arange(height)[:,None]-cr)**2) 

width=5
height=8
v = np.zeros((height, width)) # rows columns
# region center
cr = np.round(height / 2)
cc = np.round(width / 2)
# there has to be a quicker way to do this
for w in range(width):
    v[:, w] = [np.sqrt((w - cc) ** 2 + (h - cr) ** 2) for h in range(height)]

np.allclose(v, out)
# True
0 голосов
/ 06 мая 2020

Вы можете сделать это без l oop. Создайте матрицу индексов строк и матрицу индексов столбцов и примените формулу между двумя матрицами:

rows,cols = np.indices((height,width))
v         = np.sqrt((rows-height//2)**2+(cols-width//2)**2)
0 голосов
/ 06 мая 2020

Вы можете использовать scipy.spatial.distance.cdist с numpy.indices:

from scipy.spatial.distance import cdist
import numpy as np

shape = (height, width)
v = cdist(np.indices(shape).reshape(2, -1).T, [[cr, cc]]).reshape(shape)

Это дает те же результаты, что и @ yatu's broadcasting solution во всех случаях, но, как ни странно, примерно в 3 раза медленнее для большого количества входных размеров. При этом он, вероятно, немного более эффективен по пространству, поскольку он выделяет только один массив выходного размера, а не два (второй - это сумма, введенная в квадрат root). Это не должно учитываться при любом обычном вводе, с которым вы сталкиваетесь, поэтому используйте решение для широковещательной передачи. Это просто для полноты картины.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...