numpy数组的时髦行为

时间:2013-06-12 00:17:49

标签: python arrays numpy transpose indices

我希望有人可以向我解释一下我用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子集的另一种方法是一个很好的奖励。

2 个答案:

答案 0 :(得分:3)

您可以通过以下方式获得所需的结果:

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

我承认我并不完全了解numpy索引的复杂程度,但是the documentation似乎暗示了你遇到的麻烦:

  

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

     

警告:高级切片不适用。

和。 。

  

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

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

文档本身说这种索引“对于理解可能有些令人难以置信”,所以我们两个都遇到麻烦并不奇怪: - )。

答案 1 :(得分: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