Python numpy数组的时髦行为

Python numpy数组的时髦行为,python,arrays,numpy,transpose,indices,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

我希望有人能向我解释我用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,:,:][:,ind_slice].shape
(480L, 300L)
我承认我并不完全了解numpy索引的工作原理有多复杂,但似乎暗示了您遇到的麻烦:

在切片元组中使用多个non-:entry进行基本切片,就像使用单个non-:entry重复应用切片一样,其中non-:entries被依次获取(所有其他non-:entries被替换为:)。因此,
x[ind1,…,ind2,:]
的行为类似于基本切片下的
x[ind1][…,ind2,:]

警告:上述情况不适用于高级切片。

而且

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

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


文档本身说,这种索引“理解起来有点令人难以置信”,因此我们两人在这方面都有困难也就不足为奇了:-)。

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

>>> 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)

如果需要用数组替换更复杂的切片,您可能需要查看一下

实际规则非常简单。如果花式索引(在这方面,标量也是花式的,这可能很奇怪,但是…)都是连续的,那么numpy可以猜出你想把花式索引产生的维度放在哪里。如果它们不是连续的,则将它们放在第一位。如果你还记得所有奇特的索引都“作为一个”工作,这是有道理的。谢谢你勇敢地解释它,Jaime。我仍然觉得很困惑。谢谢