我有一个scipy稀疏 CSR
矩阵,大小为2M x 50k,有200M非零值(每行100个) . 我需要通过(随机分布的)索引(它是一个pandas Series
)对其120k行进行切片,然后将该子矩阵乘以大小为1x50k的稀疏向量(同样具有100个非零值) .
我这样做:
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矩阵如此之慢?即使整个矩阵的乘法花费的时间也比它少 .
-
有没有办法更快地达到最终结果?
1 回答
我在Sparse matrix slicing using list of int中解释说,这种行索引实际上是用矩阵乘法执行的 . 实际上,它构造了一个稀疏向量,其中所需的行为1,并且适当的
dot
.因此,操作的顺序并不重要,我并不感到惊讶 .
通常,稀疏矩阵不是为有效索引而设计的 . 例如,它们不会返回视图 .
csr
矩阵乘法是其最有效的操作之一 . 甚至行或列的总和也用矩阵乘法执行 .