Numpy逻辑和

时间:2017-05-10 22:23:44

标签: python numpy

我有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])

3 个答案:

答案 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]]