矩阵乘法:保持scipy.sparse.dok_matrix格式
Matrix multiplication: maintain scipy.sparse.dok_matrix format
我正在尝试使用 scipy 以 dok(键字典)格式执行稀疏线性代数计算。
当我将两个矩阵相乘时,格式从 dok 类型变为 csr 格式,这是数据和后续操作的低效格式。
如何保留dok格式?
我看过文档:
但是看不到任何信息自动类型转换或者是否以及如何避免它。
看这个例子:
from scipy.sparse import dok_matrix
my_mat = dok_matrix([[1,2], [3,4]])
print(type(my_mat.dot(my_mat)))
print(type(my_mat @ my_mat))
显示格式已更改:
<class 'scipy.sparse.csr.csr_matrix'>
<class 'scipy.sparse.csr.csr_matrix'>
只需转换回来:
result = result.todok()
CSR 可能是后续操作的低效格式(或者可能不是,我们无法判断),但它非常适合矩阵乘法。尝试使矩阵乘法代码对 DOK 结果进行原生操作会比仅转换结果慢。
正如@user2357112 所指出的,csr
适合线性代数。然而,转换的成本是巨大的。由于 dok
不是唯一支持可接受时间编辑的格式,因此值得检查另一个选项 lil
。根据您的用例,您可能会节省很多时间:
from scipy import sparse
from timeit import timeit
a = random(100,100,0.1,format='lil')
b = random(100,100,0.1,format='dok')
a
# <100x100 sparse matrix of type '<class 'numpy.float64'>'
# with 1000 stored elements in LInked List format>
b
# <100x100 sparse matrix of type '<class 'numpy.float64'>'
# with 1000 stored elements in Dictionary Of Keys format>
timeit(lambda:(a@a).tolil(),number=100)*10
# 1.491789099527523
timeit(lambda:(b@b).todok(),number=100)*10
# 4.220661079743877
请注意,在此示例中 a@a
/b@b
相当密集,如果我们选择较稀疏的情况,差异就不那么明显了:
a = random(100,100,0.01,format='lil')
b = random(100,100,0.01,format='dok')
timeit(lambda:(a@a).tolil(),number=100)*10
# 0.6880075298249722
timeit(lambda:(b@b).todok(),number=100)*10
# 0.7450748200062662
我正在尝试使用 scipy 以 dok(键字典)格式执行稀疏线性代数计算。 当我将两个矩阵相乘时,格式从 dok 类型变为 csr 格式,这是数据和后续操作的低效格式。
如何保留dok格式?
我看过文档:
但是看不到任何信息自动类型转换或者是否以及如何避免它。
看这个例子:
from scipy.sparse import dok_matrix
my_mat = dok_matrix([[1,2], [3,4]])
print(type(my_mat.dot(my_mat)))
print(type(my_mat @ my_mat))
显示格式已更改:
<class 'scipy.sparse.csr.csr_matrix'>
<class 'scipy.sparse.csr.csr_matrix'>
只需转换回来:
result = result.todok()
CSR 可能是后续操作的低效格式(或者可能不是,我们无法判断),但它非常适合矩阵乘法。尝试使矩阵乘法代码对 DOK 结果进行原生操作会比仅转换结果慢。
正如@user2357112 所指出的,csr
适合线性代数。然而,转换的成本是巨大的。由于 dok
不是唯一支持可接受时间编辑的格式,因此值得检查另一个选项 lil
。根据您的用例,您可能会节省很多时间:
from scipy import sparse
from timeit import timeit
a = random(100,100,0.1,format='lil')
b = random(100,100,0.1,format='dok')
a
# <100x100 sparse matrix of type '<class 'numpy.float64'>'
# with 1000 stored elements in LInked List format>
b
# <100x100 sparse matrix of type '<class 'numpy.float64'>'
# with 1000 stored elements in Dictionary Of Keys format>
timeit(lambda:(a@a).tolil(),number=100)*10
# 1.491789099527523
timeit(lambda:(b@b).todok(),number=100)*10
# 4.220661079743877
请注意,在此示例中 a@a
/b@b
相当密集,如果我们选择较稀疏的情况,差异就不那么明显了:
a = random(100,100,0.01,format='lil')
b = random(100,100,0.01,format='dok')
timeit(lambda:(a@a).tolil(),number=100)*10
# 0.6880075298249722
timeit(lambda:(b@b).todok(),number=100)*10
# 0.7450748200062662