【问题标题】:selective row sum matrix in numpynumpy中的选择性行和矩阵
【发布时间】:2020-10-30 21:02:01
【问题描述】:

是否有任何有效的 numpy 方法来执行以下操作: 假设我有一些大小为R X C 的矩阵M。现在假设我有另一个矩阵 E 的形状为 R X a(其中 a 只是一些常量 a < C),其中包含行索引 M(和 -1 用于填充,即 E 的每个元素都在 {-1, 0, .., R-1} 中)。例如,

M=array([[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]])

E = array([[ 0,  1],
           [ 2, -1],
           [-1,  0]])

现在,给定这些矩阵,我想生成第三个矩阵PP 的第 i 行将 包含以下行的总和 ME[i,:]。在示例中,P 将是,

P[0,:] = M[0,:] + M[1,:]
P[1,:] = M[2,:]
P[2,:] = M[0,:]

是的,使用循环执行此操作非常简单明了,我想知道是否有 任何花哨的 numpy 方法来提高效率(假设我想用大矩阵来做, 例如,200 X 200

谢谢!

【问题讨论】:

  • E 中的每行能否有 2 个或更多 -1

标签: python numpy


【解决方案1】:

一种方法是对原始数组的索引求和,然后减去由-1s 索引的最后一个引起的求和 -

out = M[E].sum(1) - M[-1]*(E==-1).sum(1)[:,None]

另一种方法是在M 的末尾填充零,以便那些-1 将索引到这些零中,因此对索引后的最终总和没有影响 -

M1 = np.vstack((M, np.zeros((1,M.shape[1]), dtype=M.dtype)))
out = M1[E].sum(1)

如果E 中每行恰好有一个或更少的-1,我们可以进一步优化-

out = M[E].sum(1)
m = (E==-1).any(1)
out[m] -= M[-1]

另一个基于张量乘法 -

np.einsum('ij,kli->kj',M, (E[...,None]==np.arange(M.shape[1])))

【讨论】:

    【解决方案2】:

    可能不是最快的,但可能具有教育意义:您所描述的操作可以被认为是与某个邻接矩阵的矩阵乘法:

    from scipy import sparse
    
    # construct adjacency matrix
    indices = E[E!=-1]
    indptr = np.concatenate([[0],np.count_nonzero(E!=-1,axis=1).cumsum()])
    data = np.ones_like(indptr)
    aux = sparse.csr_matrix((data,indices,indptr))
    
    # multiply
    aux*M
    # array([[5, 7, 9],
    #        [7, 8, 9],
    #        [1, 2, 3]], dtype=int64)
    

    【讨论】:

    • 受到这个矩阵乘法的启发,让我思考并最终得到了张量乘法。
    • @DIvakar 关于辅助矩阵的稀疏性,您在那儿给了我很大的帮助;-)
    【解决方案3】:

    您可以使用Enp.sum 索引M,其中E 中的实际索引大于或等于0。为此,我们有 where 参数:

    np.sum(M[E], where=(E>=0)[...,None], axis=1)
    
    array([[5, 7, 9],
           [7, 8, 9],
           [1, 2, 3]])
    

    我们在哪里:

    M[E]
    array([[[1, 2, 3],
            [4, 5, 6]],
    
           [[7, 8, 9],
            [7, 8, 9]],
    
           [[7, 8, 9],
            [1, 2, 3]]])
    

    在行上添加:

    (E>=0)[...,None]
    array([[[ True],
            [ True]],
    
           [[ True],
            [False]],
    
           [[False],
            [ True]]])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-25
      • 2014-11-27
      • 1970-01-01
      • 2015-03-09
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多