我有一段代码,看起来像这样:
def slice_table(table, index_vector)
to_index_product = []
array_indices = []
for i, index in enumerate(index_vector):
if isinstance(index, list):
to_index_product.append(index)
array_indices.append(i)
index_product = np.ix_(*to_index_product)
for i, multiple in enumerate(index_product):
index_vector[array_indices[i]] = multiple
index_vector = tuple(index_vector)
sliced_table = table[index_vector]
return sliced_table
table
是形状为(6, 7, 2, 2, 2, 11, 9)
的np.ndarray
。
函数的目的是挑选出满足所有给定索引的值。由于高级NumPy
索引在给定的索引数组中使用一对一的对应关系而不是所需的交叉点来挑选单独的值,因此我使用np.nx_()
构建矩阵,使我能够提取整个维度值,而不仅仅是单独的值。我最初的测试片按预期工作,所以我对代码感到满意:
index_vector = [5, [1, 2], 1, 1, 1, [0, 3, 7], slice(0, 9, None)]
# The actual `index_vector` is code-generated, hence the usage of `slice()` object
sliced_table = slice_table(table, index_vector)
sliced_table.shape # (2, 3, 9)
在这个例子中,除了第2、第6和第7维度之外,每个维度的索引都是整数,因此在切片中不存在。切片的形状从向量上很明显,因为它有2个整数作为第二个索引,3个整数作为第6个索引,切片作为第7个索引(这意味着保留了维度的整个长度)。这些例子也可以:
index_vector = [5, [1, 2], 1, 1, 1, [0, 3, 7, 8], 1]
sliced_table = slice_table(table, index_vector)
sliced_table.shape # (2, 4)
index_vector = [5, [1, 2], 1, 1, 1, [0, 3, 7, 8], [1, 3]]
sliced_table = slice_table(table, index_vector)
sliced_table.shape # (2, 4, 2)
然而,对于下面的代码,形状不是我期望的那样:
index_vector = [
slice(0, 6, None),
[1, 2],
slice(0, 2, None),
slice(0, 2, None),
slice(0, 2, None),
[0, 3, 7, 8],
1,
]
sliced_table = slice_table(table, index_vector)
sliced_table.shape # (2, 4, 6, 2, 2, 2)
我想要它的形状是(6, 2, 2, 2, 2, 4)
,但由于某种原因,有一个重新洗牌发生,形状是错误的。很难说这些元素是否错了,因为大部分table
都被None
填充了,但是从我得到的非NoneType
对象中,感觉我得到了所需的元素(我没有看到任何不需要的元素,也就是说),只是出于某种原因进行了重塑。
为什么会发生这种情况?也许我不正确地理解np.ix_()
是如何工作的,我不能只是建立一个数组索引的乘积,并提取所需的矩阵为每个维度一个接一个,就像我在我的函数?还是我不明白NumPy
索引?
正如@hpaulj所提到的,高级索引形成维度的第一个子集,然后是基本索引。由于切片对象触发基本索引,因此它们的维度被附加到由高级索引生成的子切片上。文档摘录:
理解多个高级组合的最简单方法指数可能是考虑结果的形状。有两个部件的索引操作,基本由子空间定义索引(不包括整数)和子空间从高级索引部分。索引组合的两种情况需要是区别:
高级索引以
slice
、Ellipsis
或newaxis
分隔。例如:x[arr1, :, arr2]
.高级索引彼此相邻。例如
x[..., arr1, arr2, :]
,而不是x[arr1, :, 1]
,因为1是高级索引这方面,在第一种情况下,由高级索引产生的维度操作首先出现在结果数组中,然后是子空间维度在那之后。在第二种情况下,维度来自高级索引操作同时插入到结果数组中点出它们在初始数组中的位置(后一种逻辑使简单的高级索引就像切片一样)。