python中的矩阵匹配

2024-04-24 17:10:42 发布

您现在位置:Python中文网/ 问答频道 /正文

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

 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)就好像小矩阵中的数字5将位于大矩阵的0上(因此小矩阵的中心数在大矩阵的坐标(1,1)上。在

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

目标是找到这些矩阵中可能存在的最小差。在

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


Tags: 目标定义矩阵数字差异中心small行和列
3条回答

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

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)
)

或者在一行中:

^{pr2}$

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

手工完成:

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)

输出:

^{pr2}$

如果您只对大的一个中的坐标感兴趣,请将(rowoffset,coloffset,sum)的元组存储到列表中,而不要将列表框放入列表中。您可以通过以下方式将min()与键一起使用:

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]) )

输出:

Min value for bigger matrix at  (1, 0, 24)

如果有“draws”,则只返回行数最少的列偏移量。在

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

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)

输出:

^{pr2}$

相关问题 更多 >