简体   繁体   English

使用另一个二维数组索引 NumPy 二维数组

[英]Indexing NumPy 2D array with another 2D array

I have something like我有类似的东西

m = array([[1, 2],
            [4, 5],
            [7, 8],
            [6, 2]])

and

select = array([0,1,0,0])

My target is我的目标是

result = array([1, 5, 7, 6])

I tried _ix as I read at Simplfy row AND column extraction, numpy , but this did not result in what I wanted.我在Simplfy row AND column提取 numpy 中阅读时尝试了_ix ,但这并没有得到我想要的结果。

ps Please change the title of this question if you can think of a more precise one. ps 如果你能想到更精确的问题,请更改这个问题的标题。

The numpy way to do this is by using np.choose or fancy indexing/take (see below):这样做的numpy方法是使用np.choose或花哨的 indexing/take(见下文):

m = array([[1, 2],
           [4, 5],
           [7, 8],
           [6, 2]])
select = array([0,1,0,0])

result = np.choose(select, m.T)

So there is no need for python loops, or anything, with all the speed advantages numpy gives you.所以不需要 python 循环或任何东西,numpy 为您提供所有速度优势。 mT is just needed because choose is really more a choise between the two arrays np.choose(select, (m[:,0], m[:1])) , but its straight forward to use it like this.只需要mT是因为选择实际上更像是两个数组np.choose(select, (m[:,0], m[:1])) ,但是像这样直接使用它。


Using fancy indexing :使用花哨的索引

result = m[np.arange(len(select)), select]

And if speed is very important np.take , which works on a 1D view (its quite a bit faster for some reason, but maybe not for these tiny arrays):如果速度非常重要np.take ,它适用于一维视图(由于某种原因它相当快,但可能不适用于这些小数组):

result = m.take(select+np.arange(0, len(select) * m.shape[1], m.shape[1]))

I prefer to use NP.where for indexing tasks of this sort (rather than NP.ix_ )我更喜欢使用NP.where进行此类索引任务(而不是NP.ix_

What is not mentioned in the OP is whether the result is selected by location (row/col in the source array) or by some condition (eg, m >= 5). OP 中没有提到的是结果是按位置(源数组中的行/列)还是按某些条件(例如,m >= 5)选择的。 In any event, the code snippet below covers both scenarios.无论如何,下面的代码片段涵盖了这两种情况。

Three steps:三个步骤:

  1. create the condition array ;创建条件数组

  2. generate an index array by calling NP.where , passing in this condition array;通过调用NP.where生成索引数组,传入这个条件数组; and

  3. apply this index array against the source array将此索引数组应用于源数组


>>> import numpy as NP

>>> cnd = (m==1) | (m==5) | (m==7) | (m==6)
>>> cnd
  matrix([[ True, False],
          [False,  True],
          [ True, False],
          [ True, False]], dtype=bool)

>>> # generate the index array/matrix 
>>> # by calling NP.where, passing in the condition (cnd)
>>> ndx = NP.where(cnd)
>>> ndx
  (matrix([[0, 1, 2, 3]]), matrix([[0, 1, 0, 0]]))

>>> # now apply it against the source array   
>>> m[ndx]
  matrix([[1, 5, 7, 6]])


The argument passed to NP.where, cnd , is a boolean array, which in this case, is the result from a single expression comprised of compound conditional expressions (first line above)传递给 NP.where 的参数cnd是一个布尔数组,在这种情况下,它是由复合条件表达式(上面的第一行)组成的单个表达式的结果

If constructing such a value filter doesn't apply to your particular use case, that's fine, you just need to generate the actual boolean matrix (the value of cnd ) some other way (or create it directly).如果构建这样的值过滤器不适用于您的特定用例,那很好,您只需要以其他方式生成实际的布尔矩阵( cnd的值)(或直接创建它)。

恕我直言,这是最简单的变体:

m[np.arange(4), select]

Since the title is referring to indexing a 2D array with another 2D array, the actual general numpy solution can be found here .由于标题是指用另一个2D数组索引一个2D数组,因此可以在此处找到实际的通用 numpy 解决方案。

In short: A 2D array of indices of shape (n,m) with arbitrary large dimension m , named inds , is used to access elements of another 2D array of shape (n,k), named B :简而言之:具有任意大维度 m的形状 (n,m) 索引的二维数组,名为inds ,用于访问另一个名为B的形状 (n,k) 二维数组的元素:

# array of index offsets to be added to each row of inds
offset = np.arange(0, inds.size, inds.shape[1])

# numpy.take(B, C) "flattens" arrays B and C and selects elements from B based on indices in C
Result = np.take(B, offset[:,np.newaxis]+inds)

Another solution, which doesn't use np.take and I find more intuitive, is the following:另一个不使用np.take并且我觉得更直观的解决方案如下:

B[np.expand_dims(np.arange(B.shape[0]), -1), inds]

The advantage of this syntax is that it can be used both for reading elements from B based on inds (like np.take ), as well as for assignment.这种语法的优点是它既可以用于基于inds (如np.take )从B读取元素,也可以用于赋值。

使用python怎么样?

result = array([subarray[index] for subarray, index in zip(m, select)])
result = array([m[j][0] if i==0 else m[j][1] for i,j in zip(select, range(0, len(m)))])

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

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