问题描述
考虑两个形状相同的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]]
我现在要为两个布尔变量 test1 和 test2 分配值,如下所示:
test1 :是否存在至少一个实例,其中A
列中的1和SAME B
列中的1的行差恰好为1或2?如果是这样,则 test1 = True,否则为False。
在上面的示例中,两个数组的列0的1间隔2行,因此 test1 = True。 (第2列中还有其他实例,但这没关系-我们只需要一个实例。)
test2 :A
和B
中的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:,:] + 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
,
对于Test2:您只需检查他们是否发现任何类似的索引(值为1)。
A = np.array([[1,1],[0,1,0],1]])
B = np.array([[0,[1,1]])
print(len(np.intersect1d(np.flatnonzero(A==1),np.flatnonzero(B==1)))>0))