计算在另一个数组中没有重叠的数组的出现次数

Dsc*_*oni 5 python performance numpy

我有一个mxn矩阵A,在那里m%t = n%t = 0,一个较小的txt矩阵B平铺矩阵,没有边框或重叠.我想检查是否A完全由瓷砖组成,B而不是尽可能有效地计算瓷砖作为中间步骤.此外,对于我的特殊用例,没有必要知道B.它足以测试是否A严格重复txt每个方向的每个瓦片.

数字示例:

A = [[1, 0, 1, 0],
     [0, 1, 0, 1],
     [1, 0, 1, 0],
     [0, 1, 0, 1]]
B.shape = [2,2]
--> True
B.shape = [1,1]
--> False
Run Code Online (Sandbox Code Playgroud)

到目前为止,我计算了一个比较矩阵C,它只是一个B适合以下大小的平铺A:

import numpy as np
x,y      = B.shape
x_a, y_a = A.shape
x_t = x_a/x
y_t = y_a/y
B_dash = A[:x, :y]
C = np.tile(B_dash,(x_t, y_t))
np.count_nonzero(A-C)
Run Code Online (Sandbox Code Playgroud)

有没有更快的方法,没有计算C

Div*_*kar 3

方法#1:我们似乎正在计算 A 中 B 出现的次数作为不同的块。所以,我们可以使用skimage.util.view_as_blocks-

from skimage.util import view_as_blocks as viewW

out = np.count_nonzero((viewW(A, B.shape) == B).all((2,3)))
Run Code Online (Sandbox Code Playgroud)

方法#2:继续使用NumPy,我们会 -

m1,n1 = A.shape
m2,n2 = B.shape
out = np.count_nonzero((A.reshape(m1//m2,m2,n1//n2,n2) == B[:,None]).all((1,3)))
Run Code Online (Sandbox Code Playgroud)

样本运行 -

In [274]: A
Out[274]: 
array([[2, 0, 2, 0],
       [5, 3, 5, 1],
       [3, 3, 2, 6],
       [1, 0, 3, 1]])

In [275]: B
Out[275]: 
array([[3, 3],
       [1, 0]])

In [276]: np.count_nonzero((viewW(A, B.shape) == B).all((2,3)))
Out[276]: 1



In [278]: A
Out[278]: 
array([[2, 0, 3, 3],
       [5, 3, 1, 0],
       [3, 3, 2, 6],
       [1, 0, 3, 1]])

In [279]: B
Out[279]: 
array([[3, 3],
       [1, 0]])

In [280]: np.count_nonzero((viewW(A, B.shape) == B).all((2,3)))
Out[280]: 2
Run Code Online (Sandbox Code Playgroud)