使用另一个2D阵列索引NumPy 2D阵列

时间:2012-03-27 08:03:40

标签: python numpy indexing scipy

我有类似

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

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

我的目标是

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

当我在_ix阅读时,我尝试了Simplfy row AND column extraction, numpy,但这并没有达到我想要的效果。

P.S。如果您能想到更精确的问题,请更改此问题的标题。

6 个答案:

答案 0 :(得分:12)

numpy 方法是使用np.choose或花式索引/获取(见下文):

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

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

所以不需要python循环或任何东西,numpy给你的所有速度优势。只需要m.T因为选择实际上更像是两个数组np.choose(select, (m[:,0], m[:1]))之间的选择,但它可以直接使用它。


使用花式索引

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

如果速度非常重要np.take,它适用于一维视图(由于某种原因,速度相当快,但可能不适用于这些微小数组):

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

答案 1 :(得分:2)

我更喜欢使用 NP.where 来索引此类任务(而不是 NP.ix _

OP中未提及的是结果是按位置(源数组中的行/列)还是按某些条件(例如,m> = 5)选择的。无论如何,下面的代码片段涵盖了两种情况。

三个步骤:

  1. 创建 条件数组 ;

  2. 通过调用 NP.where 生成 索引数组 ,传入此内容 条件数组;以及

  3. 对源数组

  4. 应用此索引数组
    >>> 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]])
    


    传递给NP.where, cnd 的参数是一个布尔数组,在这种情况下,是由复合条件表达式组成的单个表达式的结果(上面的第一行)

    如果构造这样的值过滤器不适用于您的特定用例,那很好,您只需要生成实际的布尔矩阵( cnd 的值) )其他一些方式(或直接创建)。

答案 2 :(得分:1)

使用python怎么样?

result = array([subarray[index] for subarray, index in zip(m, select)])

答案 3 :(得分:1)

由于标题是指将 2D 数组与另一个 2D 数组建立索引,因此可以找到一个通用的numpy解决方案here

简而言之: 形状(n,m)具有任意大尺寸m 的二维数组,名为 inds ,用于访问另一个形状的二维数组的元素(n,k) ),名为 B

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

m[np.arange(4), select]