Python 使用Scipy稀疏矩阵的高效矩阵更新和矩阵乘法
我有一个大的矩阵(236680*236680),我的电脑没有足够的内存来读取完整的矩阵,因此我认为是Scipy稀疏矩阵。我的目标是将生成的矩阵(非稀疏矩阵)乘以np.eye(观察次数)-np.one(观察次数)/稀疏矩阵的观察次数 在Scipy中,我使用以下代码,但计算量仍然很大。我的问题包括:Python 使用Scipy稀疏矩阵的高效矩阵更新和矩阵乘法,python,numpy,scipy,sparse-matrix,Python,Numpy,Scipy,Sparse Matrix,我有一个大的矩阵(236680*236680),我的电脑没有足够的内存来读取完整的矩阵,因此我认为是Scipy稀疏矩阵。我的目标是将生成的矩阵(非稀疏矩阵)乘以np.eye(观察次数)-np.one(观察次数)/稀疏矩阵的观察次数 在Scipy中,我使用以下代码,但计算量仍然很大。我的问题包括: 要生成第一个矩阵,是否有其他方法加快该过程 对于矩阵乘法,有没有办法减少内存使用,因为第一个矩阵不是稀疏的 - 更新:有没有办法提高交叉积的速度?测试了Numpy点函数和Scipy稀疏点函数 对于第一个
更新:有没有办法提高交叉积的速度?测试了Numpy点函数和Scipy稀疏点函数 对于第一个问题:数学上
arr1 = array([[ 0.8, -0.2, -0.2, -0.2, -0.2],
[-0.2, 0.8, -0.2, -0.2, -0.2],
[-0.2, -0.2, 0.8, -0.2, -0.2],
[-0.2, -0.2, -0.2, 0.8, -0.2],
[-0.2, -0.2, -0.2, -0.2, 0.8]])
相当于
arr1 = -0.2 * [[1,1,1,1,1,], + 1
[1,1,1,1,1,], 1
[1,1,1,1,1,], 1
[1,1,1,1,1,], 1
[1,1,1,1,1,]] 1
= [1] [1, 1, 1, 1, 1] * 0.2 + 1
[1] 1
[1] 1
[1] 1
[1] 1
因此,可以使用
-0.2 * np.outer([1,1,1,1,1], [1,1,1,1,1]) + scipy.sparse.identity(5)
对于第二个问题,让我滥用符号
-0.2* [1] [1, 1, 1, 1, 1] @ B + scipy.sparse.identity(5) @ B
[1]
[1]
[1]
[1]
可以简化为
np.outer([1, 1, 1, 1, 1], B.sum(axis=0)) * -0.2 + scipy.sparse.identity(5) @ B
我们不需要真正计算np.outer([1,1,1,1,1],B.sum(axis=0)),因为这将是一个密集的平方矩阵,内存可能不适合。(请注意,外积基本上在它包含的每一行中重复B.sum(axis=0)
。)
要以内存有效的方式恢复结果,只需存储
B.sum(axis=0)
和scipy.sparse.identity(5)@B
使用scipy稀疏矩阵,因为其中一个矩阵是稀疏矩阵,稀疏矩阵中的叉积函数在Numpy和scipy之间最快
对于第一个问题,“Tai的答案是基础,但我使用NUMPY.FULL函数(稍微快一点)。
对于第二个问题,使用分割整个矩阵并将较小的计算矩阵保存到文件中
from scipy import sparse
from scipy.sparse import vstack
import h5sparse
import numpy as num
fline=236680
nn=1/fline; dd=1-nn; off=0-nn
div=int(fline/(61*10))
for i in range(61*10):
divM= num.full((fline, div), off) + sparse.identity(fline,format='csc')[:,0+div*i:div+div*i]
vs=[]
for j in range(divM.shape[1]):
divMB=csr_matrix(divM.T[j]).dot(weights)
vs.append(divMB)
divapp=vstack(vs)
if i ==0:
h5f = h5sparse.File("F:/dissertation/dallastest/temp/tt1.h5")
h5f.create_dataset('sparse/matrix', data=divapp, chunks=(389,),maxshape=(None,))
else:
h5f['sparse/matrix'].append(divapp)
使用非对角填充,它不再稀疏
scipy.sparse
仅当大多数元素为0(例如80%)时才节省内存。有一些方便的函数/格式可以从对角线创建稀疏矩阵,例如sparse.diags
coo
是从3个数组创建这些矩阵的原始方法,它仍然是最基本的输入。使用csr
格式进行计算。稀疏很容易在这些格式之间转换,但有些转换需要时间。代码中的nn
是什么?代码是我实现的算法的一部分,nn用于获取矩阵中所需的值。但是更新非对角元素的循环很慢。
非对角元素需要什么样的操作?最终/预期矩阵看起来并不稀疏。您确定要将稀疏矩阵用于所需的任务吗?感谢提供代码。对于大型数据集,不可能在内存中读取整个矩阵,因此需要分割矩阵并使用一些循环。例如,np.outer([1,1,1,1,1],[1,1,1,1])必须在大数据情况下获得内存错误。我当前的代码涉及将部分矩阵按顺序保存为h5f表。在解决了一些计算瓶颈之后,我将发布我的代码。@Vicky期待看到你的工作。是的,使用外部产品可能不起作用。我不确定结果矩阵的用例,但您不需要计算所有结果,因为有许多重复的条目。例如,np.outer([1,1,1,1,1],B.sum(axis=0))
只是在每一行中重复B.sum(axis=0)
。
from scipy import sparse
from scipy.sparse import vstack
import h5sparse
import numpy as num
fline=236680
nn=1/fline; dd=1-nn; off=0-nn
div=int(fline/(61*10))
for i in range(61*10):
divM= num.full((fline, div), off) + sparse.identity(fline,format='csc')[:,0+div*i:div+div*i]
vs=[]
for j in range(divM.shape[1]):
divMB=csr_matrix(divM.T[j]).dot(weights)
vs.append(divMB)
divapp=vstack(vs)
if i ==0:
h5f = h5sparse.File("F:/dissertation/dallastest/temp/tt1.h5")
h5f.create_dataset('sparse/matrix', data=divapp, chunks=(389,),maxshape=(None,))
else:
h5f['sparse/matrix'].append(divapp)