2

基本的に、私は単純な行列乗算を実行しようとしています。具体的には、各列を抽出し、その長さで除算して正規化します。

    #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のスパース行列のドキュメントを検索しましたが、有用な情報は得られませんでした。値を直接変更できるように、関数がマトリックスへのポインター/参照を返すことを望んでいました。ありがとう

4

1 に答える 1

5

CSC 形式では、2 つの書き込み可能な属性と がdataありindices、行列のゼロ以外のエントリと対応する行インデックスを保持します。次のように、これらを有利に使用できます。

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)

実際に動作することを確認するには:

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

また、非常に高速で、楽しみを台無しにする Python ループはありません。

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
于 2013-03-04T08:21:55.847 に答える