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

Python NumPy索引-索引列表的所有成对元素,python,numpy,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

在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))
这是你需要的吗

i1 = [1,3,5]
i2 = [1,3,5]
print im[i1][:,i2].ravel()
注意:第一次索引时会创建一个临时数组。如果您的阵列非常大,则可能不需要此阵列。

请尝试:

或者您可以直接执行此操作:

>>> 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]])

别人的回答是正确的。只是为了解释为什么会发生这种情况

根据-

当像-
x[obj]
这样进行索引时,当选择对象obj是非元组序列对象、数据类型integer或bool的ndarray或至少有一个序列对象的元组或数据类型integer或bool的ndarray时,会触发高级索引

您的案例属于第二类,因此
im[(1,3,5)、(1,3,5)]
触发高级索引。在后面的文章中,我们将对此进行解释-

高级索引始终是一个索引,并作为一个索引进行迭代:

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相同

结果[i_1]
将是-
x[ind_1[i_1],ind_2[i_1],…ind_N[i_1]

文档建议使用以实现类似于基本切片的行为-

为了实现与上述基本切片类似的行为,可以使用广播。该功能有助于此广播。最好通过一个例子来理解这一点


这确实有效(如果您删除
ravel
)。但是,此处创建的临时值可能大于使用
meshgrid
创建的临时值(如果使用的列少于一半)。但是这是一个很好的方法。你是对的,我最初在整形命令中使用了
order='F'
来生成转置。啊,如果索引是列向量或行向量,那么这就行了。这看起来是最有希望的。使用第二个示例对此进行了测试,效果非常好。我使用了第二个,因为索引已经是列向量,所以它看起来像
im[ix,iy.T]
。这是相当干净,可能非常有效!
result[i_1, ..., i_M] == x[ind_1[i_1, ..., i_M], ind_2[i_1, ..., i_M],
                       ..., ind_N[i_1, ..., i_M]]