使用元组列表索引numpy数组

54

为什么我不能像这样使用一个元组索引列表来索引ndarray?

idx = [(x1, y1), ... (xn, yn)]
X[idx]

相反,我必须做一些笨拙的事情,比如

idx2 = numpy.array(idx)
X[idx2[:, 0], idx2[:, 1]] # or more generally:
X[tuple(numpy.vsplit(idx2.T, 1)[0])]

有没有更简单、更符合 Python 风格的方法?

2个回答

69
您可以使用元组列表,但是惯例与您所需的不同。 numpy 希望得到一列行索引,后跟一列列值。 显然,您想指定一个 (x,y) 对的列表。
相关文档的部分为“整数数组索引”,请参考:http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#integer-array-indexing
以下是一个示例,寻找 2d 数组中的 3 点。(在 2d 中寻找 2 点可能会令人困惑):
In [223]: idx
Out[223]: [(0, 1, 1), (2, 3, 0)]
In [224]: X[idx]
Out[224]: array([2, 7, 4])

使用您的xy索引对样式:
In [230]: idx1 = [(0,2),(1,3),(1,0)]
In [231]: [X[i] for i in idx1]
Out[231]: [2, 7, 4]

In [240]: X[tuple(np.array(idx1).T)]
Out[240]: array([2, 7, 4])

X[tuple(zip(*idx1))]是进行转换的另一种方式。在Python2中,tuple()是可选的。 zip(*...)是Python惯用语,可以反转列表嵌套。

您正在正确的轨道上:

In [242]: idx2=np.array(idx1)
In [243]: X[idx2[:,0], idx2[:,1]]
Out[243]: array([2, 7, 4])

我的tuple()更加紧凑(但不一定更具有Python风格)。鉴于numpy的惯例,需要进行某种转换。

(我们是否应该检查在n维和m点中起作用的内容?)


4
使用NumPy数组的元组,可以直接传递以索引数组:
index = tuple(np.array(list(zip(*index_tuple))))
new_array = list(prev_array[index])

2
实际上你不需要转换为数组,tuple(zip(*index_tuple))就足够了。 - Ivan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接