Python中的索引和切片是比较重要的内容,在数组处理中至关重要。这里对于2种情况做一个甄别。
索引
单元素索引
单元素索引的工作原理与其他标准 Python 序列完全相同。它是从0开始的,并接受负索引以从数组的末尾进行索引。
x = np.arange(10)
x[2]
2
x[-2]
8
无需将每个维度的索引分成自己的一组方括号。
x.shape = (2, 5) # now x is 2-dimensional
x[1, 3]
8
x[1, -1]
9
如果用少于维度数量的索引对多维数组进行索引,则会得到一个子维度数组。例如
x[0]
array([0, 1, 2, 3, 4])
也就是说,每个指定的索引都会选择对应于所选其余维度的数组。在上面的示例中,选择 0 意味着长度为 5 的剩余维度未指定,并且返回的是具有该维度和大小的数组。必须注意,返回的数组是一个视图,即它不是原始数组的副本,而是指向与原始数组相同的内存位置。在这种情况下,将返回第一个位置(0)处的 1 维数组。因此,在返回的数组上使用单个索引会导致返回单个元素。也就是说
x[0][2]
2
因此请注意 x[0, 2] == x[0][2],尽管第二种情况效率较低,因为在第一次索引后会创建一个新的临时数组,随后由 2 进行再一次索引。
切片
关于切片的相关介绍可以参考切片和步幅。
一个案例
def select(out, index):
qual_out, rot_out, width_out = out
batch_index = torch.arange(qual_out.shape[0]) # 这里需要单独提取对应的batch索引,不能直接切片使用的,索引和切片是有区别的!
label = qual_out[batch_index, :, index[:, 0], index[:, 1], index[:, 2]].squeeze() # 利用点的位置提取对应TSDF位置的相应的指标
rot = rot_out[batch_index, :, index[:, 0], index[:, 1], index[:, 2]]
width = width_out[batch_index, :, index[:, 0], index[:, 1], index[:, 2]].squeeze()
return label, rot, width
def select(out, index):
qual_out, rot_out, width_out = out
label = qual_out[: , :, index[:, 0], index[:, 1], index[:, 2]].squeeze() # 利用点的位置提取对应TSDF位置的相应的指标
rot = rot_out[: , :, index[:, 0], index[:, 1], index[:, 2]]
width = width_out[: , :, index[:, 0], index[:, 1], index[:, 2]].squeeze()
return label, rot, width
上述2段代码输出结果是大不相同的,第一段代码利用batch_index 可以对每个样本中相应的位置(从index中对应的位置组合)进行组合索引,从而选出每个样本对应位置的label、rot、width;而第二段代码直接第一个维度获取所有样本,其他维度按照广播,一次性选取了多个label、rot、width维度信息,通过调试可以发现实际上shape是不同的。
参考文献
[1]在 ndarrays 上索引。
[2]basics.indexing。