代码之家  ›  专栏  ›  技术社区  ›  ogrisel

如何用广播密集的一维数组对稀疏矩阵进行元素相乘?

  •  41
  • ogrisel  · 技术社区  · 15 年前

    >>> import numpy as np
    >>> import scipy.sparse as ssp
    
    >>> a = ssp.lil_matrix((5, 3))
    >>> a[1, 2] = -1
    >>> a[4, 1] = 2
    >>> a.todense()
    matrix([[ 0.,  0.,  0.],
            [ 0.,  0., -1.],
            [ 0.,  0.,  0.],
            [ 0.,  0.,  0.],
            [ 0.,  2.,  0.]])
    

    现在假设我有一个密集的一维数组,所有的非零分量的大小都是3(或者在我的现实生活中是50000):

    >>> d = np.ones(3) * 3
    >>> d
    array([ 3.,  3.,  3.])
    

    >>> a * d
    array([ 0., -3.,  0.,  0.,  6.])
    

    >>> a.toarray() * d
    array([[ 0.,  0.,  0.],
           [ 0.,  0., -3.],
           [ 0.,  0.,  0.],
           [ 0.,  0.,  0.],
           [ 0.,  6.,  0.]])
    

    但我不能这样做,因为对toarray()的调用将具体化不适合内存的密集版本“a”(结果也是密集的):

    >>> ssp.issparse(a.toarray())
    False
    

    你知道如何在只保留稀疏数据结构的同时,不必在“a”的列上做一个无效的python循环吗?

    3 回复  |  直到 15 年前
        1
  •  46
  •   mitmatt    15 年前

    我也在scipy.org上回复了,但我想我应该在这里添加一个答案,以防其他人在搜索时找到这个页面。

    >>> d = ssp.lil_matrix((3,3))
    >>> d.setdiag(np.ones(3)*3)
    >>> a*d
    <5x3 sparse matrix of type '<type 'numpy.float64'>'
     with 2 stored elements in Compressed Sparse Row format>
    >>> (a*d).todense()
    matrix([[ 0.,  0.,  0.],
            [ 0.,  0., -3.],
            [ 0.,  0.,  0.],
            [ 0.,  0.,  0.],
            [ 0.,  6.,  0.]])
    

    希望有帮助!

        2
  •  25
  •   salma    15 年前

    HTH公司

        3
  •  1
  •   Justin Peel    15 年前

    好吧,这里有一个简单的代码,可以做你想做的事。我不知道它是否像你想的那样高效,所以接受它或离开它:

    import scipy.sparse as ssp
    def pointmult(a,b):
        x = a.copy()
        for i in xrange(a.shape[0]):
            if x.data[i]:
                for j in xrange(len(x.data[i])):
                    x.data[i] *= b[x.rows[i]]
        return x
    

    它只适用于lil矩阵,因此如果您希望它适用于其他格式,就必须进行一些更改。