简体   繁体   English

如何使用另一个ndarray的行索引ndarray?

[英]How do I index an ndarray using rows of another ndarray?

If I have 如果我有

x = np.arange(1, 10).reshape((3,3))
# array([[1, 2, 3],
#        [4, 5, 6],
#        [7, 8, 9]])

and

ind = np.array([[1,1], [1,2]])
# array([[1, 1],
#        [1, 2]])

, how do I get use each row (axis 0) of ind to extract a cell of x? ,如何使用ind每一行(轴0)提取x的单元格? I hope to end up with the array [5, 6] . 我希望以数组[5, 6]结尾。 np.take(x, ind, axis=0) does not seem to work. np.take(x, ind, axis=0)似乎不起作用。

You could use "advanced integer indexing" by indexing x with two integer arrays, the first array for indexing the row, the second array for indexing the column: 您可以通过将x与两个整数数组一起建立索引来使用“高级整数索引” ,第一个数组用于对行进行索引,第二个数组用于对列进行索引:

In [58]: x[ind[:,0], ind[:,1]]
Out[58]: array([5, 6])
x[ind.T.tolist()]

works, too, and can also be used for multidimensional NumPy arrays. 也可以使用,也可以用于多维NumPy数组。

Why? 为什么?

NumPy arrays are indexed by tuples. NumPy数组由元组索引。 Usually, these tuples are created implicitly by python : 通常,这些元组由python隐式创建

Note 注意

In Python, x[(exp1, exp2, ..., expN)] is equivalent to x[exp1, exp2, ..., expN]; 在Python中, x[(exp1, exp2, ..., expN)]等效于x[exp1, exp2, ..., expN]; the latter is just syntactic sugar for the former. 后者只是前者的语法糖。

Note that this syntactic sugar isn't NumPy-specific. 请注意,这种语法糖不是NumPy特有的。 You could use it on dictionaries when the key is a tuple: 当键是元组时,可以在字典上使用它:

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

Actually, it's not even related to indexing: 实际上,它甚至与索引无关:

In [5]: 1, 2, 3
Out[5]: (1, 2, 3)

Thus, for your NumPy array, x = np.arange(1,10).reshape((3,3)) 因此,对于您的NumPy数组, x = np.arange(1,10).reshape((3,3))

In [11]: x[1,2]
Out[11]: 6

because 因为

In [12]: x[(1,2)]
Out[12]: 6

So, in unutbu's answer , actually a tuple containing the columns of ind is passed: 因此,在unutbu的答案中 ,实际上传递了一个包含ind列的元组:

In [21]: x[(ind[:,0], ind[:,1])]
Out[21]: array([5, 6])

with x[ind[:,0], ind[:,1]] just being an equivalent ( and recommended ) short hand notation for the same. x[ind[:,0], ind[:,1]]只是一个等同的( 建议使用 )简写形式。

Here's how that tuple looks like: 该元组的外观如下:

In [22]: (ind[:,0], ind[:,1])
Out[22]: (array([1, 1]), array([1, 2]))

We can construct the same tuple diffently from ind : tolist() returns a NumPy array's rows. 我们可以从ind构造相同的元组: tolist()返回NumPy数组的行。 Transposing switches rows and columns, so we can get a list of columns by first transposing and calling tolist on the result: 转置会切换行和列,因此我们可以通过首先转置并在结果上调用tolist来获得列列表:

In [23]: ind.T.tolist()
Out[23]: [[1, 1], [1, 2]]

Because ind is symmetric in your example, it is it's own transpose. 因为在您的示例中ind是对称的,所以它是自己的转置。 Thus, for illustration, let's use 因此,为说明起见,让我们使用

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

This can easily be converted to the tuples we want: 这可以很容易地转换为我们想要的元组:

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

Thus, 从而,

In [29]: x[tuple(ind.T.tolist())]
Out[29]: array([5, 6])

equivalently to unutbu's answer for x.ndim == 2 and ind_2.shape[1] == 2 , but also working more generally when x.ndim == ind_2.shape[1] , in case you have to work with multi-dimensional NumPy arrays. 等效于x.ndim == 2ind_2.shape[1] == 2 unutbu答案,但是在x.ndim == ind_2.shape[1]的情况下,如果必须使用多维,也可以更一般地工作NumPy数组。

Why you can drop the tuple(...) and directly use the list for indexing, I don't know. 我不知道为什么可以删除tuple(...)并直接使用列表进行索引。 Must be a NumPy thing: 必须是NumPy物件:

In [43]: x[ind_2.T.tolist()]
Out[43]: array([5, 6, 1])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM