2013-03-04 4 views
2

기본적으로 간단한 매트릭스 곱셈을 수행하려고합니다. 특히 각 열을 추출하고 길이로 나눠서 정규화합니다.scipy 스파 스 매트릭스를 제자리에 수정하십시오.

#csc sparse matrix 
    self.__WeightMatrix__ = self.__WeightMatrix__.tocsc() 
    #iterate through columns 
    for Col in xrange(self.__WeightMatrix__.shape[1]): 
     Column = self.__WeightMatrix__[:,Col].data 
     List = [x**2 for x in Column] 
     #get the column length 
     Len = math.sqrt(sum(List)) 
     #here I assumed dot(number,Column) would do a basic scalar product 
     dot((1/Len),Column) 
     #now what? how do I update the original column of the matrix, everything that have been returned are copies, which drove me nuts and missed pointers so much 

나는 scipy 스파 스 매트릭스 문서를 검색했으며 유용한 정보가 없습니다. 매트릭스의 포인터/참조를 반환하여 함수의 값을 직접 수정할 수있는 함수가 필요했습니다. 감사합니다

+0

'self .__ WeightMatrix __ [:, Col] = ...'를 사용해 보셨습니까? – Blender

+1

나는 원래 값이 변하지 않았기 때문에 [: Col]가 복사본을 반환했으며, 알고있는 한 csc sparse 행렬이 직접 인덱싱을 지원하지 않는 것으로 보이고 오류가 발생하면 그렇게. –

답변

5

CSC 형식에는 쓰기 가능 속성이 두 개 있습니다. dataindices은 매트릭스의 0이 아닌 항목과 해당 행 색인을 보유합니다.

def sparse_row_normalize(sps_mat) : 
    if sps_mat.format != 'csc' : 
     msg = 'Can only row-normalize in place with csc format, not {0}.' 
     msg = msg.format(sps_mat.format) 
     raise ValueError(msg) 
    row_norm = np.sqrt(np.bincount(sps_mat.indices, weights=mat.data * mat_data)) 
    sps_mat.data /= np.take(row_norm, sps_mat.indices) 

가 실제로 작동하는지 확인하려면 : 다음과 같이 당신은 당신의 이점에 이러한 사용할 수 있습니다

In [2]: mat = scipy.sparse.rand(10000, 10000, density=0.005, format='csc') 

In [3]: mat 
Out[3]: 
<10000x10000 sparse matrix of type '<type 'numpy.float64'>' 
    with 500000 stored elements in Compressed Sparse Column format> 

In [4]: %timeit sparse_row_normalize(mat) 
100 loops, best of 3: 14.1 ms per loop 
:

>>> mat = scipy.sparse.rand(4, 4, density=0.5, format='csc') 
>>> mat.toarray() 
array([[ 0.  , 0.  , 0.58931687, 0.31070526], 
     [ 0.24024639, 0.02767106, 0.22635696, 0.85971295], 
     [ 0.  , 0.  , 0.13613897, 0.  ], 
     [ 0.  , 0.13766507, 0.  , 0.  ]]) 
>>> mat.toarray()/np.sqrt(np.sum(mat.toarray()**2, axis=1))[:, None] 
array([[ 0.  , 0.  , 0.88458487, 0.46637926], 
     [ 0.26076366, 0.03003419, 0.24568806, 0.93313324], 
     [ 0.  , 0.  , 1.  , 0.  ], 
     [ 0.  , 1.  , 0.  , 0.  ]]) 
>>> sparse_row_normalize(mat) 
>>> mat.toarray() 
array([[ 0.  , 0.  , 0.88458487, 0.46637926], 
     [ 0.26076366, 0.03003419, 0.24568806, 0.93313324], 
     [ 0.  , 0.  , 1.  , 0.  ], 
     [ 0.  , 1.  , 0.  , 0.  ]]) 

을 그리고 그것은 또한 NumPy와 빠르고, 더 파이썬은 재미를 망치고 루프 없다

관련 문제