从向量中减去scipy.sparse矩阵的列
我正在尝试找到一种方法,将一个 scipy.sparse
矩阵中的一列减去一个 numpy
向量,但我似乎找不到不改变向量形状的方法。到目前为止,我有这样的代码:
>>> import scipy.sparse
>>> import numpy
>>> A = scipy.sparse.eye(10)
>>> A = A.tolil()
>>> x = numpy.ones(10)
>>> x
array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
>>> x.shape
(10,)
>>> x -= A[:,5].T
>>> x
matrix([[ 1., 1., 1., 1., 1., 0., 1., 1., 1., 1.]])
>>> x.shape
(1, 10)
有没有更好的方法来实现这个?我想我可以使用 numpy.reshape
,但也许还有更好的办法。
2 个回答
1
如果你的矩阵非常稀疏,最快的方法几乎肯定是使用CSC格式,然后执行以下操作:
>>> A = A.tocsc()
>>> A.sum_duplicates() # just in case...
>>> col = 5
>>> sl = slice(A.indptr[col], A.indptr[col+1])
>>> data = A.data[sl]
>>> indices = A.indices[sl]
>>> out = x.copy()
>>> out[indices] -= data
>>> out
array([ 1., 1., 1., 1., 1., 0., 1., 1., 1., 1.])
有句老话说“可读性很重要”,不过这个方法在这方面做得不是很好……
3
看起来如果你这样做的话,速度会快两倍:
x -= A[:,5].toarray().flatten()
而且这样可以避免形状问题……使用这个建议和 csr_matrix
来处理矩阵 A
,速度提升可以达到10倍……
import numpy as np
import scipy.sparse
x = np.ones(10)
A = A = scipy.sparse.eye(10).tolil()
%timeit np.asarray(x-A[:,5].T).flatten()
# 1000 loops, best of 3: 1.3 ms per loop
%timeit x-A[:,5].toarray().flatten()
# 1000 loops, best of 3: 494 µs per loop
A = A.tocsc()
%timeit np.asarray(x-A[:,5].T).flatten()
# 1000 loops, best of 3: 410 µs per loop
%timeit x-A[:,5].toarray().flatten()
# 1000 loops, best of 3: 334 µs per loop
A = A.tocsr()
%timeit np.asarray(x-A[:,5].T).flatten()
# 1000 loops, best of 3: 264 µs per loop
%timeit x-A[:,5].toarray().flatten()
# 10000 loops, best of 3: 185 µs per loop