Python 计算一个数组在另一个数组中不重叠的出现次数
我有一个Python 计算一个数组在另一个数组中不重叠的出现次数,python,performance,numpy,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
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
到目前为止,我计算了一个比较矩阵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)
有没有更快的方法,不用计算C
?Appproach\1:似乎我们正在将a中B的出现次数计算为不同的块。所以,我们可以使用-
应用方法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)))
样本运行-
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
不生成C就可以得到结果。您可以通过以下方式完成:
x,y = B.shape
x_a, y_a = A.shape
np.array_equal(A[:, :y_a-y], A[:, y:]) and np.array_equal(A[:x_a-x, :], A[x:, :])
也就是说,要比较A的第一个y_A-y
列和最后一个y_A-y
列,然后对行执行类似的操作。我还没有测试上面的代码,但是它应该更快,因为使用这个方法numpy
不会分配新的内存
最后一条语句可以优化为:
np.array_equal(A[:, :y_a-y], A[:, y:]) and np.array_equal(A[:x_a-x, :y_a], A[x:, :y_a])
因为如果第一项是
True
,我们已经知道A的列重复t次。我是否正确理解,viewW
不会生成形状为A的内存对象,而是生成形状为B的内存对象?在我的测试中,对于大型阵列,速度要快一点。尚未对内存使用情况进行基准测试。@Dschoni嗯,它在数组a
中创建了一个窗口视图,窗口参数为B
,因此没有额外的内存使用。方法#1的注意事项:/usr/lib/python2.7/dist packages/skimage/util/shape.py:92:RuntimeWarning:不复制就无法提供非连续输入数组的视图。@Dschoni是的,它需要一个连续数组。
np.array_equal(A[:, :y_a-y], A[:, y:]) and np.array_equal(A[:x_a-x, :y_a], A[x:, :y_a])