【问题标题】:Slicing rank 2 numpy array using two range objects使用两个范围对象对 2 级 numpy 数组进行切片
【发布时间】:2019-08-02 05:51:47
【问题描述】:

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

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

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

【问题讨论】:

标签: matlab numpy matrix indexing octave


【解决方案1】:

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

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

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

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

numpy 中,如果您想要一个带有“高级索引”的二维结果,您需要创建一对索引数组,它们一起广播到正确的形状:

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

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

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

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

【讨论】:

  • 你为什么希望他们做同样的事情:我对A[0:3, 0:3]A[range(3), range(3)]的区别对待感到困惑。
  • numpy 文档区分basic 索引和advanced。使用切片(冒号)和列表进行索引在行为上完全不同。
猜你喜欢
  • 1970-01-01
  • 2018-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-07
  • 2023-04-03
  • 1970-01-01
相关资源
最近更新 更多