【问题标题】:Scipy SparseEfficiencyWarning when multiplying two matrices将两个矩阵相乘时的 Scipy SparseEfficiencyWarning
【发布时间】:2021-03-19 05:06:44
【问题描述】:

我正在尝试将 scipy 稀疏矩阵与值列表相乘。代码按预期工作,但我在inv 调用中收到这两个警告:

1)SparseEfficiencyWarning: splu requires CSC matrix format warn('splu requires CSC matrix format', SparseEfficiencyWarning)

2)SparseEfficiencyWarning: 当sparse b为CSC矩阵格式时spsolve更高效 warn('spsolve is more efficient when sparse b ')

L_plus_I 矩阵是<class 'scipy.sparse.csr.csr_matrix'> 的类型。

from scipy.sparse.linalg import inv
from scipy.sparse import identity
import networkx as nx

no_of_nodes = len(g.nodes)

values = list(nx.get_node_attributes(g, 'value').values())

Laplace = nx.laplacian_matrix(g)
Identity = identity(no_of_nodes)
L_plus_I = Laplace + Identity
Inverse = inv(L_plus_I)

solutions = Inverse * values

很明显,这些是生成的,因为values 只是一个列表,但是当我尝试使其稀疏时,我得到了计算错误。另外一般来说如何提高运行时间?

【问题讨论】:

  • 您确定错误在* 行吗?这些错误看起来像是在inv 调用中生成的。完整的追溯可能有助于澄清这一点。我无法运行nx,但了解L_plus_I 可能会有所帮助。有许多不同的sparse 格式,其中一些格式比其他格式更适合计算。
  • @hpaulj 刚刚进行了检查,您是对的,警告在 inv 调用中。让我快速编辑问题。

标签: python matrix scipy


【解决方案1】:

从另一个问题的矩阵开始:

In [74]: A_sp
Out[74]: 
<5x5 sparse matrix of type '<class 'numpy.int64'>'
    with 24 stored elements in Compressed Sparse Row format>
In [75]: A_sp.A
Out[75]: 
array([[7, 4, 2, 9, 0],
       [6, 2, 5, 7, 4],
       [6, 6, 4, 3, 1],
       [5, 6, 5, 1, 2],
       [4, 8, 6, 5, 6]])

带有您警告的inv:

In [76]: inv(A_sp)
/usr/local/lib/python3.8/dist-packages/scipy/sparse/linalg/dsolve/linsolve.py:318: SparseEfficiencyWarning: splu requires CSC matrix format
  warn('splu requires CSC matrix format', SparseEfficiencyWarning)
/usr/local/lib/python3.8/dist-packages/scipy/sparse/linalg/dsolve/linsolve.py:215: SparseEfficiencyWarning: spsolve is more efficient when sparse b is in the CSC matrix format
  warn('spsolve is more efficient when sparse b '
Out[76]: 
<5x5 sparse matrix of type '<class 'numpy.float64'>'
    with 25 stored elements in Compressed Sparse Row format>

查看代码我发现inv(A) 只是`spsolve(A,I)

In [77]: Identity=sparse.identity(5)
In [79]: Identity
Out[79]: 
<5x5 sparse matrix of type '<class 'numpy.float64'>'
    with 5 stored elements (1 diagonals) in DIAgonal format>

In [80]: spsolve(A_sp, Identity)
/usr/local/lib/python3.8/dist-packages/scipy/sparse/linalg/dsolve/linsolve.py:318: SparseEfficiencyWarning: splu requires CSC matrix format
  warn('splu requires CSC matrix format', SparseEfficiencyWarning)
/usr/local/lib/python3.8/dist-packages/scipy/sparse/linalg/dsolve/linsolve.py:215: SparseEfficiencyWarning: spsolve is more efficient when sparse b is in the CSC matrix format
  warn('spsolve is more efficient when sparse b '
Out[80]: 
<5x5 sparse matrix of type '<class 'numpy.float64'>'
    with 25 stored elements in Compressed Sparse Row format>

转换Identity格式:

In [81]: spsolve(A_sp, Identity.tocsc())
/usr/local/lib/python3.8/dist-packages/scipy/sparse/linalg/dsolve/linsolve.py:318: SparseEfficiencyWarning: splu requires CSC matrix format
  warn('splu requires CSC matrix format', SparseEfficiencyWarning)
Out[81]: 
<5x5 sparse matrix of type '<class 'numpy.float64'>'
    with 25 stored elements in Compressed Sparse Row format>

也转换A:

In [82]: spsolve(A_sp.tocsc(), Identity.tocsc())
Out[82]: 
<5x5 sparse matrix of type '<class 'numpy.float64'>'
    with 25 stored elements in Compressed Sparse Column format>

是的,没有警告:)

In [83]: _.A
Out[83]: 
array([[-1.08108108e+00,  4.59459459e-01,  2.97297297e+00,
        -2.40540541e+00, -1.58603289e-16],
       [ 3.04054054e-02, -1.72297297e-01,  1.35135135e-01,
        -9.79729730e-02,  1.25000000e-01],
       [ 1.42567568e+00, -4.12162162e-01, -4.10810811e+00,
         3.62837838e+00, -2.50000000e-01],
       [ 6.21621622e-01, -1.89189189e-01, -1.45945946e+00,
         1.10810811e+00,  8.54017711e-17],
       [-1.26351351e+00,  4.93243243e-01,  3.16216216e+00,
        -2.81756757e+00,  2.50000000e-01]])

针对密集版本进行测试:

In [84]: np.linalg.inv(A_sp.A)
Out[84]: 
array([[-1.08108108e+00,  4.59459459e-01,  2.97297297e+00,
        -2.40540541e+00, -1.58603289e-16],
       [ 3.04054054e-02, -1.72297297e-01,  1.35135135e-01,
        -9.79729730e-02,  1.25000000e-01],
       [ 1.42567568e+00, -4.12162162e-01, -4.10810811e+00,
         3.62837838e+00, -2.50000000e-01],
       [ 6.21621622e-01, -1.89189189e-01, -1.45945946e+00,
         1.10810811e+00,  8.54017711e-17],
       [-1.26351351e+00,  4.93243243e-01,  3.16216216e+00,
        -2.81756757e+00,  2.50000000e-01]])

其实inv使用I = _ident_like(A),这样就够了:

In [85]: inv(A_sp.tocsc())
Out[85]: 
<5x5 sparse matrix of type '<class 'numpy.float64'>'
    with 25 stored elements in Compressed Sparse Column format>

【讨论】:

  • 一个很好的解释,np.linalg.inv 似乎计算得更快。我还对我的脚本进行了一些修改,并将其发布为任何在这里绊倒的人的答案。
【解决方案2】:

除了上面的问题,我发现这种方式计算速度也更快。

Inverse = np.linalg.inv(L_plus_I.todense())

solutions = Inverse.dot(values)

【讨论】:

    猜你喜欢
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多