首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python中的矩阵匹配

python中的矩阵匹配
EN

Stack Overflow用户
提问于 2018-11-13 18:20:11
回答 4查看 1.2K关注 0票数 3

如何找到大矩阵中小矩阵的最佳“匹配”?例如:

代码语言:javascript
复制
 small=[[1,2,3],
        [4,5,6],
        [7,8,9]]



    big=[[2,4,2,3,5],
         [6,0,1,9,0],
         [2,8,2,1,0],
         [7,7,4,2,1]]

匹配定义为矩阵中的数差,所以位置(1,1)上的匹配就好像从小到小的数在0上的大矩阵(所以从小矩阵到大矩阵的坐标(1,1)中的中心数)。

位置(1,1)中的匹配值为: m(1,1)=|2−1|+|4−2|+|2−3|+|6−4|+|0−5|+|1−6|+|2−7|+|8−8|+|2−9|=28

目标是在这些矩阵中找到最小的差分位置。

小矩阵总是有奇数的线和列,所以很容易找到它的中心。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-11-13 19:06:52

您可以迭代可行的行和列,并使用small压缩big的切片,以计算差异的总和,并使用min查找差异之间的最小值:

代码语言:javascript
复制
from itertools import islice
min(
    (
        sum(
            sum(abs(x - y) for x, y in zip(a, b))
            for a, b in zip(
                (
                    islice(r, col, col + len(small[0]))
                    for r in islice(big, row, row + len(small))
                ),
                small
            )
        ),
        (row, col)
    )
    for row in range(len(big) - len(small) + 1)
    for col in range(len(big[0]) - len(small[0]) + 1)
)

或者是一行:

代码语言:javascript
复制
min((sum(sum(abs(x - y) for x, y in zip(a, b)) for a, b in zip((islice(r, col, col + len(small[0])) for r in islice(big, row, row + len(small))), small)), (row, col)) for row in range(len(big) - len(small) + 1) for col in range(len(big[0]) - len(small[0]) + 1))

返回:(24, (1, 0))

票数 1
EN

Stack Overflow用户

发布于 2018-11-13 18:40:37

手工完成的:

代码语言:javascript
复制
small=[[1,2,3],
       [4,5,6],
       [7,8,9]]


big=[[2,4,2,3,5],
     [6,0,1,9,0],
     [2,8,2,1,0],
     [7,7,4,2,1]]

# collect all the sums    
summs= [] 

# k and j are the offset into big

for k in range(len(big)-len(small)+1):
    # add inner list for one row
    summs.append([])
    for j in range(len(big[0])-len(small[0])+1):
        s = 0
        for row in range(len(small)):
            for col in range(len(small[0])):
                s += abs(big[k+row][j+col]-small[row][col])
        # add to the inner list
        summs[-1].append(s)

print(summs)

输出:

代码语言:javascript
复制
[[28, 29, 38], [24, 31, 39]]

如果您只是对较大的和弦感兴趣,请将(rowoffset,coloffset,sum)的元组存储在列表中,不要将列表框放在框中。您可以通过这种方式使用带有密钥的min()

代码语言:javascript
复制
summs = []
for k in range(len(big)-len(small)+1):
    for j in range(len(big[0])-len(small[0])+1):
        s = 0
        for row in range(len(small)):
            for col in range(len(small[0])):
                s += abs(big[k+row][j+col]-small[row][col])
        summs .append( (k,j,s) )  # row,col, sum

print ("Min value for bigger matrix at ", min(summs , key=lambda x:x[2]) )

输出:

代码语言:javascript
复制
Min value for bigger matrix at  (1, 0, 24)

如果您有“绘制”,这将只返回最小行的,col偏移量。

票数 0
EN

Stack Overflow用户

发布于 2018-11-13 18:52:20

另一个可能的解决方案是返回big矩阵中的最小差值和坐标:

代码语言:javascript
复制
small=[[1,2,3],
       [4,5,6],
       [7,8,9]]

big=[[2,4,2,3,5],
     [6,0,1,9,0],
     [2,8,2,1,0],
     [7,7,4,2,1]]

def difference(small, matrix):
    l = len(small)
    return sum([abs(small[i][j] - matrix[i][j]) for i in range(l) for j in range(l)])

def getSubmatrices(big, smallLength):
    submatrices = []
    bigLength = len(big)
    step = (bigLength // smallLength) + 1
    for i in range(smallLength):
        for j in range(step):
            tempMatrix = [big[j+k][i:i+smallLength] for k in range(smallLength)]
            submatrices.append([i+1,j+1,tempMatrix])
    return submatrices

def minDiff(small, big):
    submatrices = getSubmatrices(big, len(small))
    diffs = [(x,y, difference(small, submatrix)) for x, y, submatrix in submatrices]
    minDiff = min(diffs, key=lambda elem: elem[2])
    return minDiff

y, x, diff = minDiff(small, big)

print("Minimum difference: ", diff)
print("X = ", x)
print("Y = ", y)

输出:

代码语言:javascript
复制
Minimum difference:  24
X =  1
Y =  2
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53287262

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档