2013-06-12 46 views
3

我希望有人能向我解释以下行为我与numpy的阵列观察:与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的子集的另一种方法将是一个很大的好处。

+0

实际的规则很简单。如果花哨的指数(和标量也是这方面的幻想,这可能很奇怪,但是......)都是*连续的* numpy可以猜测你想从哪里得到花式指数产生的维度。如果他们不是连续的,那就把他们放在首位。如果你记得所有花哨的索引都是“一体”的,这是有道理的。 – seberg

回答

3

你可以达到你想要的结果是这样的:

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

我承认我没有多么复杂numpy的索引原理的完整理解,但似乎the documentation在您遇到的麻烦提示:

基本切片与多于一个的非:在切片元组条目,动作使用单个非切片的像反复应用:条目,其中所述非:条目依次拍摄(与所有其它非:条目由:)代替。因此,在基本切片下,x[ind1,...,ind2,:]的行为如同x[ind1][...,ind2,:]

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

和。 。 。

高级索引被触发时选择对象obj是非元组序列对象,ndarray(数据类型整数或布尔的),或具有至少一个序列对象或ndarray(的数据元组类型整数或布尔)。

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

文档本身说这种索引“可能有点令人难以理解”,所以我们都遇到这个问题并不令人惊讶:-)。

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) 

如果你确实需要花哨的索引,你可以替换broadcastable阵列片:

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

你可能想,如果你需要使用数组来代替更为复杂的片来看看np.ogridnp.mgrid

+0

谢谢你勇敢的解释它,海梅。我仍然觉得很困惑。谢谢。 –