如果我有
x = np.arange(1, 10).reshape((3,3))
# array([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]])
和
ind = np.array([[1,1], [1,2]])
# array([[1, 1],
# [1, 2]])
,如何使用ind
的每一行(轴0)来提取x的单元格?我希望最终得到数组[5, 6]
。 np.take(x, ind, axis=0)
似乎不起作用。
答案 0 :(得分:1)
您可以通过使用两个整数数组索引x
来使用"advanced integer indexing",第一个数组用于索引行,第二个数组用于索引列:
In [58]: x[ind[:,0], ind[:,1]]
Out[58]: array([5, 6])
答案 1 :(得分:0)
x[ind.T.tolist()]
也适用,也可以用于多维NumPy数组。
NumPy数组由元组索引。通常,这些元组是created implicitly by python:
注意
在Python中,
x[(exp1, exp2, ..., expN)]
相当于x[exp1, exp2, ..., expN];
,后者只是前者的语法糖。
请注意,这种语法糖不是特定于NumPy的。当密钥是元组时,你可以在字典上使用它:
In [1]: d = { 'I like the number': 1, ('pi', "isn't"): 2}
In [2]: d[('pi', "isn't")]
Out[2]: 2
In [3]: d['pi', "isn't"]
Out[3]: 2
实际上,它甚至与索引无关:
In [5]: 1, 2, 3
Out[5]: (1, 2, 3)
因此,对于您的NumPy数组,x = np.arange(1,10).reshape((3,3))
In [11]: x[1,2]
Out[11]: 6
,因为
In [12]: x[(1,2)]
Out[12]: 6
因此,在unutbu's answer中,实际上传递了一个包含ind
列的元组:
In [21]: x[(ind[:,0], ind[:,1])]
Out[21]: array([5, 6])
x[ind[:,0], ind[:,1]]
只是同等的(和推荐的)简写符号。
这就是元组的样子:
In [22]: (ind[:,0], ind[:,1])
Out[22]: (array([1, 1]), array([1, 2]))
我们可以从ind
不同地构造相同的元组:tolist()
返回NumPy数组的行。转置切换行和列,因此我们可以通过首先转置并在结果上调用tolist
来获取列列表:
In [23]: ind.T.tolist()
Out[23]: [[1, 1], [1, 2]]
因为ind
在您的示例中是对称的,所以它是自己的转置。因此,为了说明,我们使用
In [24]: ind_2 = np.array([[1,1], [1,2], [0, 0]])
# array([[1, 1],
# [1, 2],
# [0, 0]])
In [25]: ind_2.T.tolist()
Out[25]: [[1, 1, 0], [1, 2, 0]]
这很容易转换为我们想要的元组:
In [27]: tuple(ind_2.T.tolist())
Out[27]: ([1, 1, 0], [1, 2, 0])
In [28]: tuple(ind.T.tolist())
Out[28]: ([1, 1], [1, 2])
因此,
In [29]: x[tuple(ind.T.tolist())]
Out[29]: array([5, 6])
等同于unutbu对x.ndim == 2
和ind_2.shape[1] == 2
的回答,但在x.ndim == ind_2.shape[1]
时也更常用,以防您必须使用多维NumPy数组。
为什么你可以删除tuple(...)
并直接使用列表进行索引,我不知道。必须是NumPy的东西:
In [43]: x[ind_2.T.tolist()]
Out[43]: array([5, 6, 1])