2014-08-27 5 views
1

Я пытаюсь найти способ вычесть столбец матрицы scipy.sparse из вектора numpy, но я не могу найти способ сделать это, не меняя форму вектора. Это то, что у меня есть до сих пор:вычесть столбец матрицы 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

Кажется, это в два раза быстрее, если вы делаете:

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

Спасибо, что ответили. Он работает отлично. Теперь о вашем предположении использования 'csr_matrix' вместо этого я не использовал этот формат, потому что я не думаю, что вы можете легко построить матрицу, добавив отдельные элементы. Кроме того, как вы это сделали? Можете ли вы предоставить код, чтобы ваш ответ был полным? – aaragon

+0

@aaragon Я приурочил его с помощью IPython ... это очень просто, используя магическую директиву 'timeit' ... Я обновлю ответ ... –

+0

Обычно вы используете разреженный формат, который подходит для процесса построения, а затем конвертируйте его к формату, который подходит для использования (здесь, расчет). Внутренне разреженный делает много этого преобразования. – hpaulj

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

Существует такая старая пословица, что «читаемость учитывается», что не слишком хорошо с ней связано, хотя ...

Смежные вопросы