Scipy:稀疏矩阵到ndarray



我有一个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 <n:v[i,0])中的条目非常慢,我实际上浪费了相当多的内存,因为v不再稀疏了。>

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

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 稀疏模块在每个版本中都变得越来越好,但它显然正在进行中,因此您可以通过直接访问对象的内部来进行很多优化。 例如,您的情况:

>>> 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.indicesc.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)

在代码审查问题中,我正在探索加快稀疏矩阵行迭代的方法,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最适合线性代数问题,而对于索引和迭代来说速度很慢。

相关内容

  • 没有找到相关文章