3

我希望有人可以向我解释我用 numpy 数组观察到的以下行为:

>>> import numpy as np
>>> data_block=np.zeros((26,480,1000))
>>> indices=np.arange(1000)
>>> indices.shape
(1000,)
>>> data_block[0,:,:].shape
(480, 1000)            #fine and dandy
>>> data_block[0,:,indices].shape
(1000, 480)            #what happened????  why the transpose????
>>> ind_slice=np.arange(300)    # this is more what I really want.
>>> data_block[0,:,ind_slice].shape
(300, 480)     # transpose again!   arghhh!

我不理解这种转置行为,这对于我想做的事情非常不方便。谁能给我解释一下?获得该子集的另一种方法data_block将是一个很大的好处。

4

2 回答 2

3

您可以通过以下方式实现您想要的结果:

>>> data_block[0,:,:][:,ind_slice].shape
(480L, 300L)

我承认我对复杂的 numpy 索引的工作原理没有完全了解,但文档似乎暗示了您遇到的麻烦:

在切片元组中具有多个 non-: 条目的基本切片,就像使用单个 non-: 条目重复应用切片一样,其中 non-: 条目被连续获取(所有其他 non-: 条目被替换为:) . 因此,x[ind1,...,ind2,:]就像x[ind1][...,ind2,:]在基本切片下一样。

警告:以上不适用于高级切片。

和。. .

Advanced indexing is triggered when the selection object, obj, is a non-tuple sequence object, an ndarray (of data type integer or bool), or a tuple with at least one sequence object or ndarray (of data type integer or bool).

因此,您通过使用ind_slice数组而不是常规切片进行索引来触发该行为。

文档本身说这种索引“可能有点难以理解”,所以我们都遇到这个问题也就不足为奇了:-)。

于 2013-06-12T00:29:19.650 回答
1

一旦你了解了花哨的索引是如何工作的,就没有什么好惊讶的了。如果您有列表或数组作为索引,它们必须都具有相同的形状,或者可以广播到一个共同的形状。该形状将是返回数组的基本形状。如果存在切片的索引,则基本形状数组中的每个条目都是多维的,因此基本形状会通过额外的条目进行扩展。虽然这似乎是一个奇怪的选择,但它确实是唯一符合多维花式索引的选择。例如,尝试计算如果您执行以下操作,您期望返回形状是什么:

>>> ind_slice=np.arange(16).reshape(4, 4)
>>> data_block[ind_slice, :, ind_slice].shape
(4, 4, 480) # No, (4, 4, 480, 4, 4) is not a better option

有几种方法可以得到你所追求的。对于您问题中的特定情况,最明显的是不使用花哨的索引,因为您可以通过切片获得您所要求的内容:

>>> data_block[0, :, :300].shape
(480, 300)

如果你确实需要花哨的索引,你可以用可广播的数组替换切片:

>>> data_block[0, np.arange(480)[:, None], ind_slice].shape
(480, 300)

您可能想看看是否需要用数组替换更复杂的切片 np.ogridnp.mgrid

于 2013-06-12T04:08:59.143 回答