NumPy Indexing - 索引列表的所有成对元素

时间:2015-09-25 05:57:33

标签: python numpy

在NumPy中使用切片时,可以获得所有成对的元素,例如:

>> im = np.arange(1,37).reshape((6, 6))
>> im[1:6:2,1:6:2]
array([[ 8, 10, 12],
       [20, 22, 34],
       [32, 34, 36]])

但是,当使用索引的列表/元组时,似乎没有遵循这种行为:

>> im[(1,3,5),(1,3,5)]
array([ 8, 22, 36])

>> im[[1,3,5],[1,3,5]]
array([ 8, 22, 36])

它只是对角线(在这种情况下)。如果您不能将索引指定为切片,则会出现问题,例如(1,3,4)(1,3,6)。对于这两个元组,我希望得到(1,1) (1,3) (1,6) (3,1) ...

的所有元素

我能想到的所有变通方法都涉及充实每一对元素,这些元素在尝试从大量图像中提取大量元素时非常昂贵。在MATLAB中,im([1,3,5],[1,3,5])做了我想要的。我知道NumPy的索引有很多技巧,我可能只是遗漏了一些细微之处。

作为结论,示例解决方法:

im[np.meshgrid([1,3,5], [1,3,5], indexing='ij')]
im[zip(*itertools.product([1,3,5], [1,3,5]))].reshape((3,3))

3 个答案:

答案 0 :(得分:3)

尝试numpy.ix_

>>> im[np.ix_((1,3,5),(1,3,5))]
array([[ 8, 10, 12],
   [20, 22, 24],
   [32, 34, 36]])

或者你可以直接这样做:

>>> ix = np.array([1, 3, 5])
>>> iy = np.array([1, 3, 5])
>>> im[ix[:, np.newaxis], iy[np.newaxis, :]]
array([[ 8, 10, 12],
       [20, 22, 24],
       [32, 34, 36]])

答案 1 :(得分:1)

这是你需要的吗?

i1 = [1,3,5]
i2 = [1,3,5]
print im[i1][:,i2].ravel()

注意在第一次索引时创建临时数组。如果您的阵列非常大,则可能不合适。

答案 2 :(得分:1)

其他人的回答是正确的。只是为了解释为什么会这样。

来自Indexing on numpy arrays -

的文档
  

当索引像 - x[obj]时 - 当选择对象obj是非元组序列对象,ndarray(数据类型为integer或bool)或元组时触发高级索引至少一个序列对象或ndarray(数据类型为integer或bool)。

您的案例属于第二个,因此im[(1,3,5),(1,3,5)]会触发高级索引。后来在documentation of Advanced indexing中解释了 -

  

高级索引始终为broadcast并迭代为一个:

result[i_1, ..., i_M] == x[ind_1[i_1, ..., i_M], ind_2[i_1, ..., i_M],
                       ..., ind_N[i_1, ..., i_M]]
     

请注意,结果形状与(广播)索引数组形状ind_1,...,ind_N相同。

它是result[i_1] - x[ind_1[i_1],ind_2[i_1],...ind_N[i_1]]

文档建议使用np.ix_来实现类似于基本切片的行为 -

  

为了实现与上述基本切片类似的行为,可以使用广播。函数ix_可以帮助进行广播。通过一个例子可以最好地理解这一点。