为什么维度的顺序随布尔索引而变化?

时间:2015-02-05 19:23:57

标签: python arrays numpy indexing boolean

当我们有M形状(a, b, c)和我们用来索引最后一个数组的索引数组v时,为什么M[i, :, v]会产生一个形状数组(d, b) {d v中的真值数量是多少?如下图所示:

In [409]: M = zeros((100, 20, 40))

In [410]: val = ones(shape=(40,), dtype="bool")

In [411]: M[0, :, :].shape
Out[411]: (20, 40)  # As expected

In [412]: M[0, :, val].shape
Out[412]: (40, 20)  # Huh?  Why (40, 20), not (20, 40)?

In [413]: M[:, :, val].shape
Out[413]: (100, 20, 40)  # s expected again

为什么M[0, :, val]形成(40, 20)而不是(20, 40)

1 个答案:

答案 0 :(得分:3)

根据文档的boolean indexing部分 http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#boolean-array-indexing

  

使用obj.nonzero()类比可以最好地理解组合多个布尔索引数组或布尔与整数索引数组。

ind = np.nonzero(val)[0]
# array([ 0,  1,  2, ...., 39], dtype=int32)
M[0, :, ind].shape   # (40,20)

现在我们转到有关组合高级和基本索引的部分 http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing

这是一种形式:x[arr1, :, arr2]

  

在第一种情况下,高级索引操作产生的维度首先出现在结果数组中,然后是子空间维度。

因此0ind部分会产生(40,)个选择,而中间的:产生(20,)。通过将:部分放在最后,结果维度为(40,20)。基本上它是这样做的,因为这种索引样式存在歧义,因此它始终选择将切片部分放在最后。

选择这些值并保持所需形状(或多或少)的方法是使用np.ix_生成索引元组。

M[np.ix_([0],np.arange(20),ind)].shape # (1, 20, 40)

您可以使用np.squeeze删除最初的1尺寸。

“纯索引数组索引”部分的末尾说明了ix_的这种用法 http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#purely-integer-array-indexing