如何将切片对象转换为布尔索引



TL;博士:

知道了NUM_ROWSrminrmax的值,如何构造布尔数组my_idx,使np.arange(NUM_ROWS)[my_idx] == np.arange(NUM_ROWS)[rmin:rmax]?如果rminrmax是阵列,并且我对所有切片[slice(from, to) for from, to in zip(rmin, rmax)]感兴趣,那么可以广播构建操作吗?


带详细信息的长版本

我在2D图像中有一个多边形阵列,我想找到图像中不包含多边形的行和列。为了快速做到这一点,我正在尝试尽可能多地对代码进行矢量化。

我计算了每个多边形在两个维度上的极值点,并获得了每个多边形的min_rowmin_colmax_rowmax_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.hstacknp.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)

最新更新