【问题标题】:Scipy sparse csr matrix returns nan on 0.0/1.0Scipy 稀疏 csr 矩阵在 0.0/1.0 上返回 nan
【发布时间】:2016-07-23 00:15:51
【问题描述】:

我在 scipy.sparse.csr_matrix 中发现了一个意外行为,这对我来说似乎是一个错误。谁能确认这不正常?我不是稀疏结构方面的专家,所以我可能会误解正确的用法。

>>> import scipy.sparse
>>> a=scipy.sparse.csr_matrix((1,1))
>>> b=scipy.sparse.csr_matrix((1,1))
>>> b[0,0]=1
/home/marco/anaconda3/envs/py35/lib/python3.5/site-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
  SparseEfficiencyWarning)
>>> a/b
matrix([[ nan]])

另一方面,numpy 可以正确处理这个问题:

>>> import numpy as np
>>> a=np.zeros((1,1))
>>> b=np.ones((1,1))
>>> a/b
array([[ 0.]])

谢谢

【问题讨论】:

  • 你试过(a/b).toarray()吗?
  • 在我看来是个错误。
  • (a/b).tolist() 返回[[nan]]a/b 是矩阵类型,所以没有toarraytodense
  • 提交错误报告:github.com/scipy/scipy/issues/6401

标签: python numpy scipy sparse-matrix


【解决方案1】:

对于稀疏矩阵/稀疏矩阵,

scipy/sparse/compressed.py

    if np.issubdtype(r.dtype, np.inexact):
        # Eldiv leaves entries outside the combined sparsity
        # pattern empty, so they must be filled manually. They are
        # always nan, so that the matrix is completely full.
        out = np.empty(self.shape, dtype=self.dtype)
        out.fill(np.nan)
        r = r.tocoo()
        out[r.row, r.col] = r.data
        out = np.matrix(out)

本节将解释该操作。

用稍微大一点的矩阵试试这个

In [69]: a=sparse.csr_matrix([[1.,0],[0,1]])
In [70]: b=sparse.csr_matrix([[1.,1],[0,1]])
In [72]: (a/b)
Out[72]: 
matrix([[  1.,  nan],
        [ nan,   1.]])

所以只要a 有 0(没有稀疏值),除法就是nan。它返回一个密集矩阵,并填写nan

如果没有此代码,稀疏元素逐元素分割会生成一个稀疏矩阵,其中包含那些“空”的对角线槽。

In [73]: a._binopt(b,'_eldiv_')
Out[73]: 
<2x2 sparse matrix of type '<class 'numpy.float64'>'
    with 2 stored elements in Compressed Sparse Row format>
In [74]: a._binopt(b,'_eldiv_').A
Out[74]: 
array([[ 1.,  0.],
       [ 0.,  1.]])

逆向可能是有益的

In [76]: b/a
Out[76]: 
matrix([[  1.,  inf],
        [ nan,   1.]])
In [77]: b._binopt(a,'_eldiv_').A
Out[77]: 
array([[  1.,  inf],
       [  0.,   1.]])

看起来combined sparsity pattern 是由分子决定的。在eliminate_zeros 之后进一步测试是这样的。

In [138]: a1=sparse.csr_matrix(np.ones((2,2)))
In [139]: a1
Out[139]: 
<2x2 sparse matrix of type '<class 'numpy.float64'>'
    with 4 stored elements in Compressed Sparse Row format>
In [140]: a1[0,1]=0
In [141]: a1
Out[141]: 
<2x2 sparse matrix of type '<class 'numpy.float64'>'
    with 4 stored elements in Compressed Sparse Row format>
In [142]: a1/b
Out[142]: 
matrix([[  1.,  nan],
        [ inf,   1.]])

【讨论】:

猜你喜欢
  • 2017-12-04
  • 2016-10-29
  • 2019-08-09
  • 1970-01-01
  • 2019-10-04
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
  • 2014-10-09
相关资源
最近更新 更多