矩阵乘法:保持scipy.sparse.dok_matrix格式



我正在尝试使用 scipy 以 dok(键字典(格式执行稀疏线性代数计算。 当我将两个矩阵相乘时,格式从 dok 类型更改为 csr 格式,这对于数据和后续操作来说是一种低效的格式。

如何保留 dok 格式?

我看过文档:

  • 西比稀疏矩阵

  • dok_matrix

但看不到任何信息自动类型转换或是否以及如何避免。

请参阅此示例:

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 结果本机操作将比仅转换结果慢。

正如@user2357112csr所指出的,它对线性代数有好处。然而,转换的成本是巨大的。由于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

相关内容

  • 没有找到相关文章

最新更新