【问题标题】:How to generate multi-dimensional 2D numpy index using a sub-index for one dimension如何使用一维的子索引生成多维 2D numpy 索引
【发布时间】:2014-11-11 23:15:01
【问题描述】:

我想使用numpy.ix_ 为二维值空间生成多维索引。但是,我需要使用子索引来查找一维的索引。例如,

    assert subindex.shape == (ny, nx)

    data = np.random.random(size=(ny,nx))

    # Generator returning the index tuples 
    def get_idx(ny,nx,subindex):
      for y in range(ny):
        for x in range(nx):
           yi = y             # This is easy
           xi = subindex[y,x] # Get the second index value from the subindex

           yield (yi,xi)

    # Generator returning the data values
    def get_data_vals(ny,nx,data,subindex):
      for y in range(ny):
        for x in range(nx):
           yi = y             # This is easy
           xi = subindex[y,x] # Get the second index value from the subindex

           yield data[y,subindex[y,x]]

所以我想使用多维索引来索引data,而不是上面的for循环,使用numpy.ix_,我想我会有类似的东西:

    idx = numpy.ix_([np.arange(ny), ?])
    data[idx]

但我不知道第二维参数应该是什么。我猜应该是涉及到numpy.choose

【问题讨论】:

  • 不清楚你到底想要什么,你能举个例子吗?
  • Ashwini,我已经稍微更新了这个问题。是不是更清楚了?

标签: python numpy indexing


【解决方案1】:

你真正想要的是:

y_idx = np.arange(ny)[:,np.newaxis]
data[y_idx, subindex]

顺便说一句,您可以使用y_idx = np.arange(ny).reshape((-1, 1)) 实现相同的效果。

我们来看一个小例子:

import numpy as np

ny, nx = 3, 5
data = np.random.rand(ny, nx)
subindex = np.random.randint(nx, size=(ny, nx))

现在

np.arange(ny)
# array([0, 1, 2])

只是“y 轴”的索引,data 的第一个维度。和

y_idx = np.arange(ny)[:,np.newaxis]
# array([[0],
#        [1],
#        [2]])

new axis 添加到此数组(在现有轴之后)并有效地转置它。现在,当您在索引表达式中将此数组与subindex 数组一起使用时,前者将broadcasted 变为后者的形状。所以y_idx 变得有效:

# array([[0, 0, 0, 0, 0],
#        [1, 1, 1, 1, 1],
#        [2, 2, 2, 2, 2]])

现在,对于每对 y_idxsubindex,您在 data 数组中查找一个元素。

Here you can find out more about "fancy indexing"

【讨论】:

  • 啊,太好了,我以前没有遇到过广播索引。这对我来说非常适用于 3D 和 4D 数组,例如
【解决方案2】:

听起来你需要做两件事:

  • 找到数据数组中的所有索引并
  • 根据其他数组子索引转换列索引。

因此,下面的代码会为所有数组位置生成索引(使用np.indices),并将其重塑为(..., 2)——代表数组中每个位置的二维坐标列表。对于每个坐标(i, j),然后我们使用提供的子索引数组转换列坐标j,然后使用转换后的索引作为新的列索引。

使用 numpy,没有必要在 for 循环中这样做——我们可以简单地一次传入所有索引:

i, j = np.indices(data.shape).reshape((-1, 2)).T
data[i, subindex[i, j]]

【讨论】:

  • @Stonz2 你当然是对的。早些时候我很着急,想为探索提供提示。我现在更新了答案以反映正在发生的事情。
  • 谢谢,效果很好。我发现.reshape((2,-1)) 为我工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
  • 1970-01-01
  • 2018-01-22
  • 2020-05-20
  • 2015-04-19
  • 1970-01-01
相关资源
最近更新 更多