Python 为什么CSR格式在选择行方面优于CSC格式?

Python 为什么CSR格式在选择行方面优于CSC格式?,python,scipy,sparse-matrix,Python,Scipy,Sparse Matrix,我正在做一个基于scipy.sparse的CSR和CSC格式的小实验。如前所述,CSC格式在处理列操作时比CSR格式更有效。所以我做了一个小实验: 来自scipy.sparse导入诊断 d=图([-1,1,1],-1,0,-1],形状=(100100)) %timeit d.tocsc()[:,1] %timeit d.tocsr()[:,1] 那么我想我把行和列弄错了。所以我尝试了另一种方法: %timeit d.tocsc()[1] %timeit d.tocsr()[1] 但在某些情况

我正在做一个基于
scipy.sparse
的CSR和CSC格式的小实验。如前所述,CSC格式在处理列操作时比CSR格式更有效。所以我做了一个小实验:

来自scipy.sparse导入诊断
d=图([-1,1,1],-1,0,-1],形状=(100100))
%timeit d.tocsc()[:,1]
%timeit d.tocsr()[:,1]
那么我想我把行和列弄错了。所以我尝试了另一种方法:

%timeit d.tocsc()[1]
%timeit d.tocsr()[1]

但在某些情况下,CSR在时间安排上优于CSC。我想知道这些结果是否有结构性原因,或者我的测试只是有偏见?

稀疏矩阵的索引很复杂,有许多变量可能会影响时间。您的测试用例是对称的,因此
csr
csc
格式几乎相同。如果形状是矩形,或者布局不同,情况可能会有所不同

此外,标量索引、切片索引和列表索引可能有所不同

请记住,无论格式如何,稀疏索引都比
numpy.ndarray
慢得多。如果需要迭代,请尽量不要使用稀疏。(如果您必须迭代,考虑直接使用“原始”稀疏属性。)< /P> 我有点惊讶于
csr
时间总是更快。但只是一点点
csc
csr
使用一个通用的
compressed
基类(
sparse.compressed.\u cs\u matrix
),但编码细节似乎有利于
csr

===

为了好玩,索引a
lil
格式

In [73]: %%timeit x=d.tolil() 
    ...: x[1,:]                                                                            
76.4 µs ± 231 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [74]: %%timeit x=d.tolil() 
    ...: x[:,1]                                                                       
118 µs ± 647 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
lil
存储中可以看出,行索引速度更快,但列索引时间也不错

lil
有一个
getrow
,它是
sparse
中与
numpy
视图最接近的东西:

In [75]: %%timeit x=d.tolil() 
    ...: x.getrow(1)                                                                          
36.7 µs ± 233 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
===

密集阵列索引,即使转换时间更快:

In [83]: %%timeit x=d.A 
    ...: x[:,1]                                                                          
277 ns ± 9.97 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [84]: timeit d.A[:,1]                                                             
197 µs ± 587 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

谢谢,这真的很有用!!两个跟进问题:不知何故,当我在笔记本电脑上测试时,tolil是三个测试中速度最慢的吗?所以,如果我的任务是在一个长循环中处理一个巨大的对角线带状矩阵,我应该牺牲内存来提高效率吗?(在你看来)
In [75]: %%timeit x=d.tolil() 
    ...: x.getrow(1)                                                                          
36.7 µs ± 233 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [83]: %%timeit x=d.A 
    ...: x[:,1]                                                                          
277 ns ± 9.97 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [84]: timeit d.A[:,1]                                                             
197 µs ± 587 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)