我有bool数组A和B,并希望得到C. C类似于A和B的逻辑AND,但是在匹配索引时有一些摆动空间。也就是说,逻辑AND将执行A [r,c] AND B [r,c],但我想要的是A [r +/- 1,c +/- 1] AND B [r +/- 1 ,c +/- 1]。有没有一种好方法可以做到这一点,理想情况下不会遍历每个索引?
>>> import numpy as np
>>> A
np.ndarray([[True, False, False, True],
[False, False, False, False],
[False, False, True, False],
[False, False, False, False])
>>> B
np.ndarray([[False, True, False, False],
[False, False, False, False],
[True, True, True, False],
[False, False, False, False])
>>> np.logical_and(A, B) # only (2,2) is True
np.ndarray([[False, False, False, False],
[False, False, False, False],
[False, False, True, False],
[False, False, False, False])
>>> C # (0,0), (1,0), and (2,1) also become True
np.ndarray([[True, False, False, False],
[True, False, False, False],
[False, True, True, False],
[False, False, False, False])
答案 0 :(得分:1)
如果我理解正确,A [r +/- 1,c +/- 1]和B [r +/- 1,c +/- 1]将产生以下结果,因为@AetherUnbound已经复制。
[[ True True True False]
[ True True True True]
[False True True True]
[False True True True]]
如果这是所需的输出,我们可以对a和b使用卷积运算,最后做一个逻辑和。
<强>解决方案强>
from scipy import ndimage
#define a convolution filter with size 3*3
f = np.full((3,3),True, dtype=bool)
#Convolve A and B using a 3*3 filter and then do a logical and in the end.
np.logical_and(ndimage.convolve(A,f,mode='constant', cval=False),ndimage.convolve(B,f,mode='constant', cval=False))
Out[766]:
array([[ True, True, True, False],
[ True, True, True, True],
[False, True, True, True],
[False, True, True, True]], dtype=bool)
答案 1 :(得分:1)
正如其他评论者指出的那样,您所使用的符号表示该数组将具有2个元素的重叠半径。如果你想要一个1元素的重叠半径,试试这个:
import numpy as np
A=np.array([[True, False, False, True],
[False, False, False, False],
[False, False, True, False],
[False, False, False, False]])
B=np.array([[False, True, False, False],
[False, False, False, False],
[True, True, True, False],
[False, False, False, False]])
def conv(mat):
mat_pad=np.pad(mat,1,'constant')
return mat+.5*(np.roll(mat_pad,1,0)[1:-1,1:-1]+np.roll(mat_pad,-1,0)[1:-1,1:-1]+np.roll(mat_pad,1,1)[1:-1,1:-1]+np.roll(mat_pad,-1,1)[1:-1,1:-1])
C=conv(A)*conv(B)>=.5
print(C)
这是方法返回:
array([[ True, True, False, False],
[False, False, False, False],
[False, True, True, False],
[False, False, False, False]], dtype=bool)
答案 2 :(得分:0)
这是一个潜在的解决方案。如果在它周围有3x3方格的True
,则检查A上的每个点,并对B执行相同的操作。如果两者都是True
,则该索引也是True
。它没有提供您想要的输出,但我可能需要进一步澄清才能实现这一目标。
import numpy as np
A = np.array([[True, False, False, True], [False, False, False, False], [False, False, True, False], [False, False, False, False]])
B = np.array([[False, True, False, False], [False, False, False, False], [True, True, True, False], [False, False, False, False]])
def and3x3(arr, x, y):
subarr = arr[max(0, x-1):x+2, max(0, y-1):y+2]
return np.any(subarr)
C = np.zeros_like(B)
for a in range(A.shape[0]):
for b in range(A.shape[1]):
t1 = and3x3(A, a, b)
t2 = and3x3(B, a, b)
C[a, b] = t1 * t2
print(C)
输出:
[[ True True True False]
[ True True True True]
[False True True True]
[False True True True]]