如何使用数组(或任何支持添加的其他任何东西,以便它可以偏移)干净地索引numpy数组

lnm*_*rer 11 python indexing numpy offset

解释我的问题最简单的方法可能是一个例子,所以让我定义一些数组:

>>> test = arange(25).reshape((5,5))
>>> test
array([[ 0,  1,  2,  3,  4],
      [ 5,  6,  7,  8,  9],
      [10, 11, 12, 13, 14],
      [15, 16, 17, 18, 19],
      [20, 21, 22, 23, 24]])
>>> Xinds = array([1,2,3])
>>> Yinds = array([1,2,3])
Run Code Online (Sandbox Code Playgroud)

现在,如果我想要第1行,第2行和第3行以及第0列中的元素,我可以去:

>>> test[Yinds,0]
array([ 5, 10, 15])
Run Code Online (Sandbox Code Playgroud)

如果我想要第1,2和3行以及所有列中的项目,我可以去:

>>> test[Yinds, :]
array([[ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试扩展它以获取第1,2和3行以及第1,2和3列中的元素,那就太惊讶了! - 我改为(1,1),(2,2)和(3,3)中的元素

>>> test[Yinds, Xinds]
array([ 6, 12, 18])
Run Code Online (Sandbox Code Playgroud)

而不是我想要的:

>>> test[Yinds, :][:, Xinds]
array([[ 6,  7,  8],
       [11, 12, 13],
       [16, 17, 18]])
>>> test[1:4,1:4]
array([[ 6,  7,  8],
       [11, 12, 13],
       [16, 17, 18]])
Run Code Online (Sandbox Code Playgroud)

我意识到我可以定义一个切片,但我希望能够为索引添加一个偏移量(例如Yinds + offset),而这不能用切片来完成.

我可以做点什么

>>> xStart = 1
>>> xEnd   = 4
>>> yStart = 1
>>> yEnd   = 4

>>> offset = 1
>>> test[yStart+offset:yEnd+offset, xStart+offset:xEnd+offset]
...
Run Code Online (Sandbox Code Playgroud)

要么

>>> Xinds = array([1,4])
>>> Yinds = array([1,4])

>>> offset = 1
>>> test[slice(*(Yinds+offset)), slice(*(Xinds+offset))]
...
Run Code Online (Sandbox Code Playgroud)

但两者都不是特别干净.

将加法运算符修补到切片中的猴子似乎不是一个选项,并且继承自切片以添加运算符似乎也不起作用; 我得到错误,"类型'切片'不是一个可接受的基类型".(*Grumble*这不会是Ruby*Grumble中的问题*)

所以,我的问题是,用一种可以存储和偏移的东西来访问一个(一维以上)子阵列最干净的方法是什么?

目前的选项:

  • test [Yinds + offset,:] [:,Xinds + offset]
  • test [yStart + offset:yEnd + offset,xStart + offset:xEnd + offset]
  • test [slice(*(Yinds + offset)),slice(*(Xinds + offset))]

DSM*_*DSM 13

我不完全确定你想要什么,但也许ix_会有所帮助?我想我见过的人对numpy的了解比我在类似环境中使用它更多.

>>> from numpy import array, arange, ix_
>>> a = arange(25).reshape(5,5)
>>> Xinds = array([1,2,3])
>>> Yinds = array([1,2,3])
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])
>>> a[ix_(Xinds, Yinds)]
array([[ 6,  7,  8],
       [11, 12, 13],
       [16, 17, 18]])
>>> a[ix_(Xinds+1, Yinds)]
array([[11, 12, 13],
       [16, 17, 18],
       [21, 22, 23]])
>>> Y2inds = array([1,3,4])
>>> a[ix_(Xinds, Y2inds)]
array([[ 6,  8,  9],
       [11, 13, 14],
       [16, 18, 19]])
>>> a[ix_(Xinds, Y2inds-1)]
array([[ 5,  7,  8],
       [10, 12, 13],
       [15, 17, 18]])
Run Code Online (Sandbox Code Playgroud)