在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))
答案 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)
其他人的回答是正确的。只是为了解释为什么会这样。
的文档当索引像 -
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_可以帮助进行广播。通过一个例子可以最好地理解这一点。