【问题标题】:Scipy: Sparse Matrix to ndarrayScipy:稀疏矩阵到 ndarray
【发布时间】:2013-11-13 06:45:53
【问题描述】:

我有一个 CSC 格式的矩阵 A,我只索引其中一列

b = A[:,col]

产生一个 (n x 1) 矩阵。我想做的是:

v  = M * b

其中 M 是 CSR 中的 (n x n) 矩阵。结果 v 是一个 (n x 1) CSR 矩阵。我需要迭代 v 中的值(实际上不包括 0)并检索满足特殊标准的一个元素的索引(注意:未选择稀疏矩阵格式来适应该特定操作,但一般矩阵 x 矩阵乘积应该是CSR * CSC 最快,对吧?)

问题是,迭代 CSR 格式向量 (0

谁能告诉我如何执行这些操作,以便我可以快速迭代结果向量,同时保持与复制相关的内存开销很小?

IN: M (CSR-Matrix), A (CSC-Matrix), col_index
v = M * A[:,col_index]
for entries in v:
    do stuff

是否也可以以某种方式加快对 CSC 矩阵中列的“高级”索引?在代码中的其他点,我必须提取 A 的子矩阵(不能重新格式化以允许切片,因此使用索引数组),其中包括所有列的给定子集。 A[:,idxlist] 在行分析时需要很长时间。

期待您的建议

【问题讨论】:

    标签: scipy linear-algebra sparse-matrix


    【解决方案1】:

    scipy sparse 模块在每个版本中都在变得更好,但很明显它正在进行中,因此您可以通过直接访问对象的内部来进行很多优化。例如。你的情况:

    >>> a = sps.rand(5, 20, density=0.2, format='csr')
    >>> b = sps.rand(20, 1, density=0.2, format='csc')
    >>> c = a * b
    >>> c.A
    array([[ 0.30331594],
           [ 0.        ],
           [ 0.12198742],
           [ 0.34350077],
           [ 0.        ]])
    

    你可以得到c的非零条目为c.data

    >>> c.data
    array([ 0.30331594,  0.12198742,  0.34350077])
    

    获取相应的行号有点棘手。可能最简单的方法是将您的输出转换为 CSC 格式,因为您将它们直接作为 c.indices,而 c.data 仍将与以前相同:

    >>> c.tocsc().indices
    array([0, 2, 3])
    >>> c.tocsc().data
    array([ 0.30331594,  0.12198742,  0.34350077])
    

    但如果你不喜欢它,你可以在不进行转换的情况下提取它们:

    >>> np.where(c.indptr[:-1] != c.indptr[1:])[0]
    array([0, 2, 3], dtype=int64)
    

    所以如果你想找到,例如最大值及其行号,您可以这样做:

    >>> row_idx = np.where(c.indptr[:-1] != c.indptr[1:])[0]
    >>> idx = np.argmax(c.data)
    >>> c.data[idx], row_idx[idx]
    (0.34350077450601624, 3)
    

    【讨论】:

    • 谢谢。现在我最终将 M 更改为 CSC 矩阵。由于转换(CSC * CSC 矩阵 mult 而不是 CSR * CSC),使用相当大的矩阵进行基准测试并没有真正显示代码中的任何特别减速。但是,作为一个很好的副作用,我会立即获得索引数组中的所有非零索引,就像你说的那样:)
    【解决方案2】:

    在代码审查问题中,我正在探索加快稀疏矩阵行迭代的方法,https://codereview.stackexchange.com/questions/32664/numpy-scipy-optimization/33566#33566

    csr getrow 出奇的慢。至少对于那个小测试用例,将稀疏矩阵转换为密集数组并使用常规 numpy 索引(使用np.nonzero 获取稀疏条目)会更快。将矩阵转换为 lil 并在 zip(X.data, X.rows) 上进行常规 Python 迭代同样快。

    我的印象是scipy.sparse 最适合线性代数问题,而索引和迭代速度较慢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      • 2023-04-10
      • 2017-07-21
      • 2011-11-28
      相关资源
      最近更新 更多