【问题标题】:Row Division in Scipy Sparse MatrixScipy稀疏矩阵中的行划分
【发布时间】:2018-08-21 14:06:14
【问题描述】:

我想将稀疏矩阵的行除以数组中给出的标量。

例如,我有一个csr_matrix C

C = [[2,4,6], [5,10,15]]
D = [2,5]

我希望C除法后的结果是:

result = [[1, 2, 3], [1, 2, 3]]

我已经使用我们用于numpy 数组的方法进行了尝试:

result = C / D[:,None]

但这似乎真的很慢。如何在稀疏矩阵中有效地做到这一点?

【问题讨论】:

标签: python numpy scipy sparse-matrix


【解决方案1】:

问题:我想将稀疏矩阵的行除以数组中给出的标量。 例如: C = [[2,4,6], [5,10,15]] D = [2,5]

答案:使用稀疏矩阵接口提供的"multiply" - 它允许将矩阵“逐点”乘以矩阵以及向量和标量

    C = [[2,4,6], [5,10,15]]
    D = [2,5]

从 scipy.sparse 导入 csr_matrix

c = csr_matrix(C)
c2 = c.multiply(1/np.array(D).reshape(2,1))

c2.toarray()

'输出:' 数组([[ 2, 4, 6], [ 5, 10, 15]], dtype=int64)

PS

感谢亚历山大·基里林

【讨论】:

    【解决方案2】:

    如果您首先将D 转换为numpy.matrix(我假设您可以这样做,除非D 太大而无法放入内存),那么您可以运行

    C.multiply(1.0 / D.T)
    

    得到你想要的。

    【讨论】:

      【解决方案3】:

      方法#1

      这是使用indexing 手动复制的稀疏矩阵解决方案-

      from scipy.sparse import csr_matrix
      
      r,c = C.nonzero()
      rD_sp = csr_matrix(((1.0/D)[r], (r,c)), shape=(C.shape))
      out = C.multiply(rD_sp)
      

      输出是一个稀疏矩阵,与 C / D[:,None] 的输出相反,它创建了一个完整的矩阵。因此,建议的方法可以节省内存。

      使用np.repeat 而非索引进行复制可能会提高性能 -

      val = np.repeat(1.0/D, C.getnnz(axis=1))
      rD_sp = csr_matrix((val, (r,c)), shape=(C.shape))
      

      方法 #2

      另一种方法可能涉及稀疏矩阵的data 方法,它为我们提供了in-place 结果的稀疏矩阵的平面视图,并且还避免使用nonzero,就像这样 -

      val = np.repeat(D, C.getnnz(axis=1))
      C.data /= val
      

      【讨论】:

      • 太棒了!它就像一个魅力!在我的数据集上,我的方法需要 60 秒。现在它需要 1 秒。谢谢。
      • @user3787291 Approach #2 怎么样?
      • 是的,它也有效。如果我需要按列划分怎么办?您如何按列划分?
      • @user3787291 我陷入了这个问题,但必须按列进行。只需要一个小的修改。 (1.0/D)[r] 更改为 (1.0/D)[c] rD_sp = csr_matrix(((1.0/D)[c], (r,c)), shape=(C.shape))
      【解决方案4】:

      一行代码:result = [[C[i][j]/D[i] for j in range(len(C[0]))] for i in range(len(D))]

      C = [[2,4,6], [5,10,15]] #len(C[0]) = 3
      D = [2,5] # len(D) = 2
      result = [[C[i][j]/D[i] for j in range(len(C[0]))] for i in range(len(D))]
      print result
      

      【讨论】:

      • 我没有按照要求看到 csr_matrix 的这项工作。
      猜你喜欢
      • 1970-01-01
      • 2017-10-20
      • 1970-01-01
      • 2016-05-26
      • 1970-01-01
      • 2017-03-26
      • 2017-03-31
      • 2023-04-10
      • 2017-07-21
      相关资源
      最近更新 更多