我有一个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
。
问题:
为什么按行划分CSR矩阵如此之慢?即使整个矩阵的乘法花费的时间也比它少。
有没有办法更快地达到最终结果?
答案 0 :(得分:1)
我在Sparse matrix slicing using list of int中解释说,这种行索引实际上是用矩阵乘法执行的。实际上,它构造了一个稀疏向量,其中包含所需行的1,并执行相应的dot
。
所以我对操作顺序无关紧要并不感到惊讶。
通常,稀疏矩阵不是为有效索引而设计的。例如,它们不会返回视图。 csr
矩阵乘法是其最有效的操作之一。甚至行或列的总和也是用矩阵乘法执行的。
答案 1 :(得分:0)
我遇到了同样的问题,我的解决方案是编写一个行提取程序,该行提取程序依赖于numpy数组的索引而不是稀疏矩阵乘法。 See my approach here。
答案 2 :(得分:0)
如果您有足够的RAM内存,则可以转换为tolil(),切片速度应该更快。