本文介绍了获取矩阵的相邻元素之和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个矩阵例如.

I have a matrixeg.

[[4,5,0,0,0],
 [5,1,2,1,0],
 [0,2,3,2,0],
 [0,1,2,1,0],
 [0,0,0,0,0]]

对于矩阵中的每个元素,我试图获取其相邻对角元素的总和及其相邻水平和垂直元素的总和.

For each element in the matrix, I am trying to get the sum of its adjacent diagonal elements and the sum of its adjacent horizontal and vertical elements.

例如,以矩阵中间的3为例,我试图计算对角相邻元素(1)与水平和垂直相邻元素(2)的总和.对于拐角和边缘情况,我想忽略没有元素的区域,例如(对于左上角的4,我想获得对角线相邻的1的总和以及水平和垂直相邻的总和5个.

Taking the 3 in the middle of the matrix for example, I am trying to calculate the sum of the diagonally adjacent elements (the 1's) and the horizontally and vertically adjacent elements (the 2's).For corner and edge cases, I want to disregard the areas where there are no elements eg.(for the 4 in the upper left, I'd want to get the sum of the diagonally adjacent 1 and the sum of the horizontally and vertically adjacent 5's.

在python中最有效的方法是什么?

What would be the most efficient way to do this in python?

到目前为止,我已经提出

So far i've come up with

diagonals = lambda x,y:[(x-1, y-1), (x-1,y+1), (x+1,y-1), (x+1,y+1)]
horiz_vert= lambda x,y:[(x,y+1), (x,y-1), (x+1,y), (x-1,y)]

获取索引,但这些索引未考虑边缘情况和拐角情况.

to get the indices but these don't take into account the edge and corner cases.

推荐答案

解决此任务的正确工具似乎是卷积.您只需要定义将在每个位置应用的过滤器(对角线邻居的总和"或垂直/水平邻居的总和")就可以了.

The right tool to solve this task appears to be convolution. You only need to define the filters that will be applied in each position ("sum of diagonal neighbors" or "sum of vertical/horizontal neighbors") and you're done.

import numpy as np
import scipy.signal

D = np.array([[4,5,0,0,0],
              [5,1,2,1,0],
              [0,2,3,2,0],
              [0,1,2,1,0],
              [0,0,0,0,0]])

h_diag = np.array([[1,0,1], [0,0,0], [1,0,1]])
h_hv   = np.array([[0,1,0], [1,0,1], [0,1,0]])

以下是过滤器的外观:

>>> h_diag
array([[1, 0, 1],
       [0, 0, 0],
       [1, 0, 1]])
>>> h_hv
array([[0, 1, 0],
       [1, 0, 1],
       [0, 1, 0]])

您可以将2D卷积视为在矩阵上移动滤镜并在每个位置计算逐元素乘法的和.严格来说,过滤器需要镜像,但是在您的情况下它们始终是对称的.这是在网上找到的原理的随机说明:

You can think of 2D convolution as of shifting the filter across your matrix and calculating in each position the sum of the element-wise multiplication. Strictly speaking, the filters need to be mirrored, but in your case they are symmetric anyway. Here's a random illustration of the principle as found on the web:

与您的案例唯一的不同是,我们希望将过滤器放置在任何地方,包括边界"或角"位置.这可以通过将原始矩阵D零填充来实现,以便可以将滤镜的中心放置在例如在(0,0)位置.

The only difference to your case is that we want to place the filters everywhere, including the "boundary" or "corner" positions. This can be achieved by zero-padding the original matrix D such that the center of the filter can be placed e.g. in position (0,0).

好消息!它已经在Numpy/Scipy中实现,并且是非常有效的实现!现在,您只需将D与过滤器h卷积即可.

Good news! It's already implemented in Numpy/Scipy and it's a very efficient implementation! Now you just construct a matrix by convolving D with a filter h.

>>> scipy.signal.convolve2d(D, h_diag, mode='same')
array([[1, 7, 2, 2, 1],
       [7, 7, 9, 3, 2],
       [2, 9, 4, 4, 2],
       [2, 3, 4, 3, 2],
       [1, 2, 2, 2, 1]])

>>> scipy.signal.convolve2d(D, h_hv, mode='same')
array([[10,  5,  7,  1,  0],
       [ 5, 14,  5,  4,  1],
       [ 7,  5,  8,  5,  2],
       [ 1,  4,  5,  4,  1],
       [ 0,  1,  2,  1,  0]])

从这些矩阵中,您可以读取每个位置所需的总和.例如.原始矩阵D中的中心元素,即D[2,2],在对角线上被4包围,在水平/垂直邻接上被4包围.因此,卷积输出中在位置(2,2)的条目是48.位置D[0,0]仅具有一个对角邻居(1)和两个水平/垂直邻居(55).卷积输出矩阵中的条目与预期的110一样.

From these matrices you can read off the required sums in each position. E.g. the central element in your original matrix D, i.e. D[2,2] is surrounded by 4 ones on the diagonals and 4 twos on the horizontal/vertical adjacency. The entries in the convolution output at the position (2,2) are therefore 4 and 8. The position D[0,0] has only one diagonal neighbor (1) and two horizontal/vertical neighbors (5 and 5). The entries in the convolution output matrices are as expected 1 and 10.

这篇关于获取矩阵的相邻元素之和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-15 06:58