Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 矩阵乘法:保持scipy.sparse.dok_矩阵格式_Python_Numpy_Scipy_Sparse Matrix_Linear Algebra - Fatal编程技术网

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

Python 矩阵乘法:保持scipy.sparse.dok_矩阵格式,python,numpy,scipy,sparse-matrix,linear-algebra,Python,Numpy,Scipy,Sparse Matrix,Linear Algebra,我正在尝试使用scipy以dok(键字典)格式执行稀疏线性代数计算。 当我将两个矩阵相乘时,格式从dok类型更改为csr格式,这对于数据和后续操作来说是一种低效的格式 如何保持dok格式 我已经看过这些文件: 但看不到任何自动类型转换的信息,也看不到是否以及如何避免自动类型转换 请参见此示例: 从scipy.sparse导入dok_矩阵 my_mat=dok_矩阵([[1,2],[3,4]) 打印(键入(my_mat.dot(my_mat))) 打印(键入(my_mat@my_mat))

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

如何保持dok格式

我已经看过这些文件:

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

请参见此示例:

从scipy.sparse导入dok_矩阵
my_mat=dok_矩阵([[1,2],[3,4])
打印(键入(my_mat.dot(my_mat)))
打印(键入(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

把我想要的矩阵相乘并不好。我对一种格式不感兴趣,这种格式在矩阵的维度上除了对数开销之外,没有任何其他开销。例如,
python my_mat=dok_matrix((1000000000000000000))my_mat[50000000,50000000]=1.0打印(键入((my_mat@my_mat))
在我的计算机上计算要花费3秒以上的时间。@Patrick:然后调整代码,以消除所有零行和零列,如果您的数据是如此稀疏的话。你可以稍后再把它们放回去。如果不可能在没有向量/矩阵维数的多项式开销的情况下在scipy中执行线性代数,请告诉我。我不知道零的先验位置,它们在整个操作过程中都会发生变化。@Patrick:你可能不知道先验,但你可以检查一下。在任何情况下,如果SciPy确实有专门针对稀疏矩阵的矩阵乘法的工具,那么它可能会通过取出全零行和列,进行乘法,然后转换回来,正如我现在所建议的,如果我可以删除零,而不用编写一个与非零元素数量成比例的python循环,这将是令人满意的。这可能吗?我之所以要使用scipy,首先是为了避免python开销。
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