我有一个大矩阵(236680 * 236680),我的电脑没有足够的内存来读取完整的矩阵,所以我正在考虑Scipy稀疏矩阵 . 我的目标是将生成的矩阵(非稀疏)乘以np.eye(观察次数)-np.ones(观察次数)/用稀疏矩阵观察的次数 .
在Scipy中,我使用以下代码,但计算仍然很大 . 我的问题包括:
-
生成第一个矩阵,有没有其他方法来加速这个过程?
-
用于矩阵乘法,有没有办法减少内存使用量,因为第一个矩阵不稀疏?
from scipy.sparse import lil_matrix
fline=5
nn=1/fline
M=lil_matrix((fline,fline))
M.setdiag(values=1-nn,k=0)
for i in range(fline)[1:]:
M.setdiag(values=0-nn,k=i)
M.setdiag(values=0-nn,k=-i)
#the first matrix is:
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]])
#the second matrix is:
array([[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0.],
[1., 0., 1., 0., 0.]])
a2=M.dot(B)
#the final expected results
array([[-0.2, 0. , -0.2, 0.6, 0. ],
[-0.2, 0. , -0.2, -0.4, 0. ],
[-0.2, 0. , -0.2, 0.6, 0. ],
[-0.2, 0. , -0.2, -0.4, 0. ],
[ 0.8, 0. , 0.8, -0.4, 0. ]])
更新:有没有办法提高跨产品的速度?测试Numpy dot和Scipy稀疏点函数 .
2 回答
对于第一个问题:数学上,
相当于
因此,它可以使用生成
对于第二个问题,让我滥用符号
可以减少到
人们不需要真正计算
np.outer([1, 1, 1, 1, 1], B.sum(axis=0))
,因为这将是一个内存可能不适合的密集方阵 . (请注意,外部产品基本上在其包含的每一行中重复B.sum(axis=0)
. )To recover the results in a memory efficient way ,您只需要存储
B.sum(axis=0)
和scipy.sparse.identity(5) @ B
.使用Scipy稀疏矩阵,因为其中一个matrics是稀疏矩阵,稀疏矩阵中的叉积函数是Numpy和Scipy之间最快的 .
对于第一个问题,@ Tai的答案是基础,但我使用numpy.full函数(稍快一点) .
对于第二个问题,使用划分整个矩阵并将较小的计算矩阵保存在文件中 .