scipy稀疏CSR矩阵

时间:2017-02-09 02:10:15

标签: python pandas matrix scipy sparse-matrix

我有一个scipy稀疏CSR矩阵,大小为2M x 50k,有200M非零值(每行100个)。我需要通过(随机分布的)索引(这是一个pandas Series)对其120k行进行切片,然后将该子矩阵乘以大小为1x50k的稀疏向量(也包含100个非零值)。 / p>

我这样做:

slice = matrix[index.tolist(), :]
result = slice.dot(vector.T).T.toarray()[0]  # returns 1x120k array

切片需要0.7s(慢),然后乘法需要0.05s

相反,我可以先将整个矩阵相乘,然后对结果进行切片:

result = matrix.dot(vector.T).T.toarray()[0]
result_sliced = result[index.tolist()]  # returns 1x120k array

在这种情况下,乘法需要0.65s,然后切片需要0.015s

问题:

  1. 为什么按行划分CSR矩阵如此之慢?即使整个矩阵的乘法花费的时间也比它少。

  2. 有没有办法更快地达到最终结果?

3 个答案:

答案 0 :(得分:1)

我在Sparse matrix slicing using list of int中解释说,这种行索引实际上是用矩阵乘法执行的。实际上,它构造了一个稀疏向量,其中包含所需行的1,并执行相应的dot

所以我对操作顺序无关紧要并不感到惊讶。

通常,稀疏矩阵不是为有效索引而设计的。例如,它们不会返回视图。 csr矩阵乘法是其最有效的操作之一。甚至行或列的总和也是用矩阵乘法执行的。

答案 1 :(得分:0)

我遇到了同样的问题,我的解决方案是编写一个行提取程序,该行提取程序依赖于numpy数组的索引而不是稀疏矩阵乘法。 See my approach here

答案 2 :(得分:0)

如果您有足够的RAM内存,则可以转换为tolil(),切片速度应该更快。