使用两个范围对象切片等级 2 numpy 数组

Slicing rank 2 numpy array using two range objects

我有一个二级数​​组,想用切片来索引它。 如果我就地创建切片,我会得到预期的结果:

A = rand(3,3)
assert(allclose(A[0:3, 0:3], A))

另一方面,如果我提前创建切片,索引不会按预期运行(至少从 octave/matlab 用户的角度来看,两种方法产生相同的结果):

A = rand(3,3)
i = range(0,3)
j = range(0,3)
assert(allclose(A[i, j], A))
# AssertionError

为什么这些方法会产生不同的结果?

为什么你期望他们做同样的事情? numpy 这种索引与 MATLAB 不同。

In [6]: arr = np.arange(9).reshape(3,3)

In [7]: arr[range(3),range(3)]
Out[7]: array([0, 4, 8])

有了范围(或相同值的列表或数组),它 returns 一个一维数组,在本例中是二维数组的对角线。此索引选择一组点,而不是一个块。

numpy中,如果你想要一个带有'advanced indexing'的二维结果,你需要创建一对索引数组,它们一起广播到正确的形状:

In [8]: arr[np.arange(3)[:,None],range(3)]
Out[8]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

在 MATLAB/octave 中,select 一个块很容易,但 select 单个元素要难得多。

arr(sub2ind([3,3],[1,2,3],[1,2,3]))

一般来说,要了解 numpy 高级索引,您需要了解广播 - 它适用于索引以及加法等数学运算。