在 python 中为大型 scipy.sparse 矩阵运算分配内存
allocate memory in python for large scipy.sparse matrix operations
有没有办法为 scipy 稀疏矩阵函数分配内存来处理大型数据集?
具体来说,我正在尝试使用非对称最小二乘平滑(转换为 python and the original here)对大型质谱数据集(长度约为 60,000)执行基线校正。
该函数(见下文)使用 scipy.sparse 矩阵运算。
def baseline_als(y, lam, p, niter):
L = len(y)
D = sparse.csc_matrix(np.diff(np.eye(L), 2))
w = np.ones(L)
for i in xrange(niter):
W = sparse.spdiags(w, 0, L, L)
Z = W + lam * D.dot(D.transpose())
z = spsolve(Z, w*y)
w = p * (y > z) + (1-p) * (y < z)
return z
当我传递长度为 10,000 或更少的数据集时没有问题:
baseline_als(np.ones(10000),100,0.1,10)
但是当传递更大的数据集时,例如
baseline_als(np.ones(50000), 100, 0.1, 10)
我得到一个 MemoryError,对于行
D = sparse.csc_matrix(np.diff(np.eye(L), 2))
尝试改变
D = sparse.csc_matrix(np.diff(np.eye(L), 2))
到
diag = np.ones(L - 2)
D = sparse.spdiags([diag, -2*diag, diag], [0, -1, -2], L, L-2)
D
将是 DIA
角形格式的稀疏矩阵。如果事实证明 CSC 格式很重要,请使用 tocsc()
方法转换它:
D = sparse.spdiags([diag, -2*diag, diag], [0, -1, -2], L, L-2).tocsc()
下例说明新旧版本生成相同的矩阵:
In [67]: from scipy import sparse
In [68]: L = 8
原文:
In [69]: D = sparse.csc_matrix(np.diff(np.eye(L), 2))
In [70]: D.A
Out[70]:
array([[ 1., 0., 0., 0., 0., 0.],
[-2., 1., 0., 0., 0., 0.],
[ 1., -2., 1., 0., 0., 0.],
[ 0., 1., -2., 1., 0., 0.],
[ 0., 0., 1., -2., 1., 0.],
[ 0., 0., 0., 1., -2., 1.],
[ 0., 0., 0., 0., 1., -2.],
[ 0., 0., 0., 0., 0., 1.]])
新版本:
In [71]: diag = np.ones(L - 2)
In [72]: D = sparse.spdiags([diag, -2*diag, diag], [0, -1, -2], L, L-2)
In [73]: D.A
Out[73]:
array([[ 1., 0., 0., 0., 0., 0.],
[-2., 1., 0., 0., 0., 0.],
[ 1., -2., 1., 0., 0., 0.],
[ 0., 1., -2., 1., 0., 0.],
[ 0., 0., 1., -2., 1., 0.],
[ 0., 0., 0., 1., -2., 1.],
[ 0., 0., 0., 0., 1., -2.],
[ 0., 0., 0., 0., 0., 1.]])
有没有办法为 scipy 稀疏矩阵函数分配内存来处理大型数据集?
具体来说,我正在尝试使用非对称最小二乘平滑(转换为 python
该函数(见下文)使用 scipy.sparse 矩阵运算。
def baseline_als(y, lam, p, niter):
L = len(y)
D = sparse.csc_matrix(np.diff(np.eye(L), 2))
w = np.ones(L)
for i in xrange(niter):
W = sparse.spdiags(w, 0, L, L)
Z = W + lam * D.dot(D.transpose())
z = spsolve(Z, w*y)
w = p * (y > z) + (1-p) * (y < z)
return z
当我传递长度为 10,000 或更少的数据集时没有问题:
baseline_als(np.ones(10000),100,0.1,10)
但是当传递更大的数据集时,例如
baseline_als(np.ones(50000), 100, 0.1, 10)
我得到一个 MemoryError,对于行
D = sparse.csc_matrix(np.diff(np.eye(L), 2))
尝试改变
D = sparse.csc_matrix(np.diff(np.eye(L), 2))
到
diag = np.ones(L - 2)
D = sparse.spdiags([diag, -2*diag, diag], [0, -1, -2], L, L-2)
D
将是 DIA
角形格式的稀疏矩阵。如果事实证明 CSC 格式很重要,请使用 tocsc()
方法转换它:
D = sparse.spdiags([diag, -2*diag, diag], [0, -1, -2], L, L-2).tocsc()
下例说明新旧版本生成相同的矩阵:
In [67]: from scipy import sparse
In [68]: L = 8
原文:
In [69]: D = sparse.csc_matrix(np.diff(np.eye(L), 2))
In [70]: D.A
Out[70]:
array([[ 1., 0., 0., 0., 0., 0.],
[-2., 1., 0., 0., 0., 0.],
[ 1., -2., 1., 0., 0., 0.],
[ 0., 1., -2., 1., 0., 0.],
[ 0., 0., 1., -2., 1., 0.],
[ 0., 0., 0., 1., -2., 1.],
[ 0., 0., 0., 0., 1., -2.],
[ 0., 0., 0., 0., 0., 1.]])
新版本:
In [71]: diag = np.ones(L - 2)
In [72]: D = sparse.spdiags([diag, -2*diag, diag], [0, -1, -2], L, L-2)
In [73]: D.A
Out[73]:
array([[ 1., 0., 0., 0., 0., 0.],
[-2., 1., 0., 0., 0., 0.],
[ 1., -2., 1., 0., 0., 0.],
[ 0., 1., -2., 1., 0., 0.],
[ 0., 0., 1., -2., 1., 0.],
[ 0., 0., 0., 1., -2., 1.],
[ 0., 0., 0., 0., 1., -2.],
[ 0., 0., 0., 0., 0., 1.]])