2D numpy数组-检查所有相邻项是否相等
我有一个大小为n乘m的布尔数组,这个数组用来表示不同的区域。如果某个位置在区域内,就标记为true;如果不在区域内,就标记为false。例如:
r = np.array([[ 0, 0, 1, 1, 1],
[ 0, 1, 1, 0, 0],
[ 0, 1, 1, 1, 0],
[ 1, 1, 1, 0, 0],
[ 1, 1, 0, 0, 0]])
区域之间的边界可以用一个大小为(n-1)乘(m-1)的数组来表示,这个数组中的每个点代表着四个值之间的关系。如果这四个值都是一样的,说明你不在区域的边界上;如果有任何一个值不同,那就说明你在边界上。对于上面的r:
l = np.array([[ 1, 1, 1, 1],
[ 1, 0, 1, 1],
[ 1, 0, 1, 1],
[ 0, 1, 1, 0]])
有没有什么好的方法可以高效地实现这个呢?我尝试过双向比较,但这样会重复计算。有没有什么2D的差异函数?或者其他的解决办法?
2 个回答
2
已经有一个很好的答案被选中了,但我喜欢那些写起来简单、容易理解的解决方案,所以我还是想分享这个:
from scipy.signal import convolve2d
kernel = np.array(((1, 1), (1, 1)))
x = convolve2d(r, kernel, mode="valid") # sum all the neighboring values (and mode handles the boundary issues)
x[x==4] = 0 # set the elements that sum to 4 to zero (the ones that sum to 0 are already 0)
x[x>0] = 1 # anything greater than one is set to 1
[[1 1 1 1]
[1 0 1 1]
[1 0 1 1]
[0 1 1 0]]
6
这段代码会测试被 True
包围的 points。
tmp = r[1:] & r[:-1]
l = np.logical_not(tmp[:, 1:] & tmp[:, :-1])
然后你可以用同样的方法测试被 False
包围的 points,最后把它们结合起来。
r = np.logical_not(r)
tmp = r[1:] & r[:-1]
l &= np.logical_not(tmp[:, 1:] & tmp[:, :-1])
print l.astype(int)
# [[1 1 1 1]
# [1 0 1 1]
# [1 0 1 1]
# [0 1 1 0]]