比较两个 numpy 数组是否符合两个条件

Comparing two numpy arrays for compliance with two conditions

考虑两个具有相同形状的 numpy 数组,A 和 B,由 1 和 0 组成。显示一个小例子:

A = [[1 0 0 1]         B = [[0 0 0 0]
     [0 0 1 0]              [0 0 0 0]
     [0 0 0 0]              [1 1 0 0]
     [0 0 0 0]              [0 0 1 0]
     [0 0 1 1]]             [0 1 0 1]]

我现在想给两个布尔变量test1test2赋值如下:

test1:是否至少有一个实例,其中 A 列中的 1 和 SAME B 列中的 1 具有行差异正好是 1 或 2?如果是,则 test1 = True,否则为 False。

在上面的示例中,两个数组的第 0 列都有 1,它们相隔 2 行,因此 test1 = True。 (第 2 列中还有其他实例,但这并不重要 - 我们只需要一个实例。)

test2AB中的1值是否数组地址不同?如果是,则 test2 = True,否则为 False。

在上面的例子中,两个数组都有[4,3] = 1,所以test2 = False.

我正在努力寻找一种有效的方法来执行此操作,希望得到一些帮助。

您可以使用 masked_arrays,第二个任务您可以执行:

A_m = np.ma.masked_equal(A, 0)
B_m = np.ma.masked_equal(B, 0)

test2 = np.any((A_m==B_m).compressed())

完成第一项任务的一种天真的方法是:

test1 = np.any((np.vstack((A_m[:-1],A_m[:-2],A_m[1:],A_m[2:]))==np.vstack((B_m[1:],B_m[2:],B_m[:-1],B_m[:-2]))).compressed())

输出:

True
True

这里有一个简单的方法来测试两个数组是否在同一列中有一个元素相隔一个元素(仅在一个方向):

(A[1:, :] * B[:-1, :]).any(axis=None)

所以你可以做到

test1 = (A[1:, :] * B[:-1, :] + A[:-1, :] * B[1:, :]).any(axis=None) or (A[2:, :] * B[:-2, :] + A[:-2, :] * B[2:, :]).any(axis=None)

第二个测试可以通过将位置转换为索引,将它们堆叠在一起,并使用np.unique 来计算重复次数来完成。重复项只能来自两个数组中的相同索引,因为数组永远不会有重复的索引。我们可以通过使用 flatnonzero 而不是 nonzero:

来进一步加快计算速度
test2 = np.all(np.unique(np.concatenate((np.flatnonzero(A), np.flatnonzero(B))), return_counts=True)[1] == 1)

更有效的测试将以类似的方式使用 np.intersect1d

test2 = not np.intersect1d(np.flatnonzero(A), np.flatnonzero(B)).size

对于测试 2:您可以检查他们是否找到了任何相似的索引值 1。

A =  np.array([[1, 0, 0, 1],[0, 0, 1, 0],[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 1, 1]])
B = np.array([[0, 0, 0, 0],[0, 0, 0, 0],[1, 1, 0, 0],[0, 0, 1, 0],[0, 1, 0, 1]])
print(len(np.intersect1d(np.flatnonzero(A==1),np.flatnonzero(B==1)))>0))