2014-08-27 159 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.]) 

有一句老話說「可讀性很重要」,雖然這不太適用,但...