TL;博士:
知道了NUM_ROWS
、rmin
和rmax
的值,如何构造布尔数组my_idx
,使np.arange(NUM_ROWS)[my_idx] == np.arange(NUM_ROWS)[rmin:rmax]
?如果rmin
和rmax
是阵列,并且我对所有切片[slice(from, to) for from, to in zip(rmin, rmax)]
感兴趣,那么可以广播构建操作吗?
带详细信息的长版本
我在2D图像中有一个多边形阵列,我想找到图像中不包含多边形的行和列。为了快速做到这一点,我正在尝试尽可能多地对代码进行矢量化。
我计算了每个多边形在两个维度上的极值点,并获得了每个多边形的min_row
、min_col
、max_row
和max_col
值。让我们只考虑行(对于列,这是相同的算法),并假设,例如,这些是我为两个多边形获得的值:
NUM_ROWS = 10
# Two intervals: slice(1,5) and slice(7,8)
row_mins = np.array([1, 7], dtype=np.int32)
row_maxs = np.array([5, 8], dtype=np.int32)
我现在想以一种等效于的方式合并区间
row_mask = np.zeros(NUM_ROWS)
for rmin, rmax in zip(row_mins, row_maxs):
row_mask[rmin:rmax] = 1
但是,它应该避免for循环和在rowmask中重复设置值。我想通过将每个范围变成一个bool数组并使用np.logical_or.reduce()
来实现这一点,但我找不到生成等效于[rmin:rmax]
索引的bool数组的方法。有没有一种方法可以将切片对象转换为布尔索引?
编辑:找到了正确的方法。
我被纠正了。有一种方法可以打开np.r_
中的切片列表,它就像使用tuple()
一样简单。这意味着,一旦将切片映射到rmin和rmax数组,就可以简单地将它们转换为具有np.r_
的数组,并使用它将掩码的值更新为1。
import numpy as np
NUM_ROWS = 15
## 3 slices (1:5), (7:10), (12:14)
row_mins = np.array([1, 7, 12])
row_maxs = np.array([5, 10, 14])
mask = np.zeros(NUM_ROWS) #Zeros
slices = list(map(slice,row_mins,row_maxs)) #List of slices
mask[np.r_[tuple(slices)]]=1 #get ranges from list of slices and then update mask
mask
array([0., 1., 1., 1., 1., 0., 0., 1., 1., 1., 0., 0., 1., 1., 0.])
我推荐的旧方法-
如果要制作一个包含多个slices
的掩码,则可以在不使用for循环的情况下执行(矢量化),方法是将np.hstack
与np.arange
一起使用以获取所有索引,然后将它们设置为1。
import numpy as np
NUM_ROWS = 15
## 3 slices (1:5), (7:10), (12:14)
row_mins = np.array([1, 7, 12])
row_maxs = np.array([5, 10, 14])
mask = np.zeros(NUM_ROWS) #Zeros
idx = np.hstack(list(map(np.arange,row_mins,row_maxs))) #Indexes to choose
mask[idx]=1 #Set to 1
mask
array([0., 1., 1., 1., 1., 0., 0., 1., 1., 1., 0., 0., 1., 1., 0.])
编辑:另一种方式-
你可以使用np.eye()
-
s = slice(1,4)
mask = np.eye(10)[s].sum(0)
print(mask)
[0. 1. 1. 1. 0. 0. 0. 0. 0. 0.]
在切片列表上-
masks = [np.eye(NUM_ROWS)[slice(i,j)].sum(0) for i,j in zip(row_mins, row_maxs)]
final = np.logical_or.reduce(masks)
final
array([False, True, True, True, True, False, False, True, True,
True, False, False, True, True, False])
希望这有帮助:
arr = np.arange(NUM_ROWS)
bool_indices = (arr >= rmin) & (arr < rmax)
当您在寻找两者之间的交集时,它们之间的逻辑and
应该会创建该数组。
使用解决方案的其余部分:
arrs = [(b >= rmin) & (b<rmax) for rmin,rmax in zip(row_mins,row_maxs)]
mask = np.logical_or.reduce(arrs)