2014-08-27 145 views
1

我试图找到一种方法从numpy矢量中减去scipy.sparse矩阵的一列,但我似乎无法找到一种方法来做到这一点,而无需更改形状的矢量。这是我到目前为止有:从矢量减去scipy.sparse矩阵的列

>>> 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

现在看来,这是快两倍,如果你这样做:使用矩阵A这项建议,并csr_matrix给出10倍的速度高达

x -= A[:,5].toarray().flatten() 

,它避免了造型问题......

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 
+0

感谢您的回答。它工作得很好。现在关于您使用'csr_matrix'的建议,我没有使用这种格式,因为我不认为您可以通过添加单独的元素轻松构建矩阵。另外,你是如何计时的?你能否提供代码,以便你的答案完整? – aaragon 2014-08-27 19:17:21

+0

@aaragon我使用IPython对其进行了计时...使用magic指令'timeit'非常简单...我将更新答案... – 2014-08-27 19:18:39

+0

通常您使用适合构建过程的稀疏格式,然后将其转换到适合使用的格式(这里是计算)。内部稀疏进行了很多转换。 – hpaulj 2014-08-27 21:37:07

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.]) 

有一句老话说“可读性很重要”,虽然这不太适用,但...