У меня есть разреженная матрица, и мне нужно создать новую соседнюю матрицу для каждого индекса.
Ниже я оставляю представление данных в матрице NxM
. Для каждого из элементов матрицы мне нужно получить соседей в сечении KxK
. С этой информацией он сгенерирует матрицу NMxKK
, которая содержит в каждой строке индексы соседних KK элемента.
Я задал похожий вопрос некоторое время назад, но разница в том, что теперь данные структурированы, поэтому я могу обойтись без KdTree.
Эта новая матрица используется для расчета расстояния от ненулевых соседей, и с этими расстояниями ассоциируется вес с каждым соседом, чтобы окончательно оценить желаемое значение как средневзвешенное значение соседей. .
Заранее спасибо!
UPDATE
У меня есть данные, подобные изображениям (сгенерированные с помощью функции generate_data
), и мне нужно выполнить следующую операцию.
Учитывая матрицу filter / kernel / NxN
, где N
- размер ядра, определенный мной, для ненулевых значений рассчитайте расстояния по отношению к центральному пикселю. В качестве примера возьмем значение 20
, которое находится в положении (1, 8)
изображения. Принимая матрицу 5x5
, интересующие ненулевые значения равны 40
(в (0, 6)
), 37
(в (1, 6)
) и 25
(в (3, 10)
), с расстояниями 2.23606798
, 2
и 2.82842712
соответственно (получено с учетом евклидовой нормы между индексами).
На этом шаге мне нужно получить матрицу res
:
[[0. 2.23606798 2. 0. 0. ]
[0. 0. 0. 0. 0. ]
[0. 0. 1. 0. 0. ]
[0. 0. 0. 0. 0. ]
[0. 0. 0. 0. 2.82842712]]
Мне нужно также получить 1.
в центре матрицы, чтобы также учесть значение, в котором я стою (расстояние до которого 0.
).
С этими значениями я получаю маску с ненулевыми значениями и вычисляю веса на основе распределения Гаусса:
import scipy.stats as st
mask = 0 < res
gauss = st.norm.pdf(res) # or st.norm.pdf(mask * kernel(5))
[[0. , 0.03274718, 0.05399097, 0. , 0. ],
[0. , 0. , 0. , 0. , 0. ],
[0. , 0. , 0.39894228, 0. , 0. ],
[0. , 0. , 0. , 0. , 0. ],
[0. , 0. , 0. , 0. , 0.00730688]])
total = gauss.sum() # 0.4929873057962355
Наконец, с этими весами я вычисляю вес и окончательное значение пикселя путем интерполяции значений.
val[1, 8] = 0.03274718 * 40 / total + 0.05399097 * 37 / total + 0.39894228 * 20 / total + 0.00730688 * 25 / total
То же самое я должен сделать для каждого пикселя (думаю, мне нужно добавить kernel_size padding // 2
, чтобы иметь возможность использовать весь массив).
Вот мой сценарий
import matplotlib.pylab as plt
import numpy as np
import scipy.stats as st
from scipy import sparse
def generate_data(m, n, density):
s = 64 * sparse.random(m, n, density=density).A
return s.astype(np.int8)
def plot_matrix(matrix):
for (j, i), label in np.ndenumerate(s):
plt.text(i, j, label, ha='center', va='center')
plt.imshow(matrix)
plt.show()
def kernel(n):
n = n if n % 2 != 0 else n + 1
mid = n // 2
m = np.ndarray((n, n, 2))
for i in range(n):
for j in range(n):
m[i, j] = np.array([i, j])
return np.linalg.norm(m - [mid, mid], axis=2)
s = generate_data(10, 14, 0.25)
plot_matrix(s)