Scipy稀疏矩阵在赋值后变为密集矩阵

时间:2016-06-07 08:38:35

标签: scipy sparse-matrix

alpha = csr_matrix((1000,1000),dtype=np.float32)
beta = csr_matrix((1,1000),dtype=np.float32)
alpha[0,:] = beta

启动后,alpha和beta应该是稀疏矩阵,没有存储元素。但是在将beta分配给第一行alpha后,alpha变为非稀疏,并且在alpha中存储了1000个零。我知道我可以使用eliminate_zeros()将alpha转回稀疏矩阵,但有没有更好的方法呢?

1 个答案:

答案 0 :(得分:1)

当我复制你的步骤时,我得到了

In [131]: alpha[0,:]=beta
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:730: 
   SparseEfficiencyWarning: Changing the sparsity structure of a
   csr_matrix is expensive. lil_matrix is more efficient.
   SparseEfficiencyWarning)

因此,这是你正在做的事情的第一个指标,开发人员认为这是不明智的。

我们可以深入研究csr __setitem__代码,但我的猜测是它将您的beta转换为密集,然后进行分配。并且不会自动执行eliminate_zeros步骤(在分配期间或之后)。

通常人们为什么会这样做a[...]=...?通常它是构建稀疏矩阵的。可以将非零值清零,但不足以作为特殊情况处理。

由于各种原因,在稀疏矩阵中有0个值是可能的。您甚至可以直接将{0}插入alpha.data。这就是为什么要进行清理' eliminate_zerosprune等方法。即使nonzero也会应用!=0掩码

    # convert to COOrdinate format
    A = self.tocoo()
    nz_mask = A.data != 0
    return (A.row[nz_mask],A.col[nz_mask])

在正常的稀疏练习中,您以coo或其他格式构建数据,然后转换为csr进行计算。矩阵乘法是它的优点。这构造了一个新的稀疏矩阵。可以修改csr,但不鼓励。

====================

alpha.__setitem__??(在Ipython中)显示

def __setitem__(self, index, x):
    # Process arrays from IndexMixin
    i, j = self._unpack_index(index)
    i, j = self._index_to_arrays(i, j)

    if isspmatrix(x):
        x = x.toarray()
    ....
    self._set_many(i, j, x.ravel())

所以是的,它在执行赋值之前将RHS转换为密集数组。