python - 稀疏矩阵的元素除法,忽略 0/0
问题描述
我有两个稀疏矩阵 E 和 D,它们在同一位置具有非零条目。现在我想拥有E/D
一个稀疏矩阵,仅在 D 非零时定义。
例如下面的代码:
import numpy as np
import scipy
E_full = np.matrix([[1.4536000e-02, 0.0000000e+00, 0.0000000e+00, 1.7914321e+00, 2.6854320e-01, 4.1742600e-01, 0.0000000e+00],
[9.8659000e-03, 0.0000000e+00, 0.0000000e+00, 1.9106752e+00, 5.7283640e-01, 1.4840370e-01, 0.0000000e+00],
[1.3920000e-04, 0.0000000e+00, 0.0000000e+00, 9.4346500e-02, 2.8285900e-02, 4.3967800e-02, 0.0000000e+00],
[0.0000000e+00, 4.5182676e+00, 0.0000000e+00, 0.0000000e+00, 7.3000000e-06, 1.5100000e-05, 4.0746900e-02],
[0.0000000e+00, 0.0000000e+00, 3.4002088e+00, 4.6826200e-02, 0.0000000e+00, 2.4246900e-02, 3.4529236e+00]])
D_full = np.matrix([[0.36666667, 0. , 0. , 0.33333333, 0.2 , 0.1 , 0. ],
[0.23333333, 0. , 0. , 0.33333333, 0.4 , 0.03333333, 0. ],
[0.06666667, 0. , 0. , 0.33333333, 0.4 , 0.2 , 0. ],
[0. , 0.63636364, 0. , 0. , 0.04545455, 0.03030303, 0.28787879],
[0. , 0. , 0.33333333, 0.33333333, 0. , 0.22222222, 0.11111111]])
E = scipy.sparse.dok_matrix(E_full)
D = scipy.sparse.dok_matrix(D_full)
然后除法E/D
产生一个完整的矩阵。
matrix([[3.96436360e-02, nan, nan, 5.37429635e+00, 1.34271600e+00, 4.17426000e+00, nan],
[4.22824292e-02, nan, nan, 5.73202566e+00, 1.43209100e+00, 4.45211145e+00, nan],
[2.08799990e-03, nan, nan, 2.83039503e-01, 7.07147500e-02, 2.19839000e-01, nan],
[ nan, 7.10013476e+00, nan, nan, 1.60599984e-04, 4.98300005e-04, 1.41541862e-01],
[ nan, nan, 1.02006265e+01, 1.40478601e-01, nan, 1.09111051e-01, 3.10763127e+01]])
我还尝试了一个不同的包。
import sparse
sparse.COO(E) / sparse.COO(D)
这给了我一个错误。
ValueError: Performing this operation would produce a dense result: <ufunc 'true_divide'>
所以它也尝试创建一个密集矩阵。
我理解这是因为0/0 = nan
. 但无论如何我对这些价值观不感兴趣。那么我怎样才能避免计算它们呢?
解决方案
一个简单的实现使用multiply
:
def sparse_divide_nonzero(a, b):
inv_b = b.copy()
inv_b.data = 1 / inv_b.data
return a.multiply(inv_b)
用作:
import scipy as sp
import scipy.sparse
N, M = 4, 4
M1 = sp.sparse.random(N, M, 0.5, 'csr')
M2 = sp.sparse.random(N, M, 0.5, 'csr')
M3 = sparse_divide_nonzero(M1, M2)
print(M1, '\n')
# (0, 1) 0.9360024198546736
# (1, 1) 0.625073080022902
# (1, 2) 0.4086612951451881
# (2, 0) 0.06864456080221182
# (2, 1) 0.9871542989102963
# (2, 3) 0.4371900022237898
# (3, 0) 0.12121502419640318
# (3, 3) 0.22950388104392383
print(M2, '\n')
# (1, 0) 0.9753308317090571
# (1, 2) 0.29870724277296024
# (1, 3) 0.21116220574550637
# (2, 1) 0.5039729514070662
# (2, 2) 0.4463809800134303
# (3, 0) 0.36751994181969416
# (3, 1) 0.6189763803260612
# (3, 2) 0.3870101687623324
print(M3, '\n')
# (1, 2) 1.368099719817645
# (2, 1) 1.9587446035629748
# (3, 0) 0.3298189034212229
推荐阅读
- javascript - 如何从此 NodeList 中提取数据?
- csv - Racket:在函数中使用“csv-reading”包
- docker - docker 限制容器网络访问
- javascript - 角度/形式整数验证器
- python - 保存功能在 python 3.8.5 中没有弹出窗口,也没有显示任何错误,这是什么问题?
- ruby-on-rails - Rails:如果 Json 中有不同的属性,如何在 csv 文件中添加数据头?
- swift - CoreML 自动将 int 转换为浮点数
- business-objects - 促销管理 - 错误 - 无法检索根 LCM 文件夹
- python - 一旦我得到超过特定条件限制的项目,如何停止列表理解
- flutter - 如何将 CSS BoxShadow 转换为 Flutter BoxShadow?