python - 从稀疏 coo_matrix 获得的对角稀疏矩阵

标签 python scipy sparse-matrix

我使用 coo_matrix 格式在 Python 中构建了一些稀疏矩阵 M。我想找到一种有效的计算方法:

A = M + M.T - D

其中DM对其对角线的限制(M可能非常大)。我找不到一种在保持 coo_matrix 格式的同时有效构建 D 的方法。有什么想法吗?

D = scipy.sparse.spdiags(coo_matrix.diagonal(M),0,M.shape[0],M.shape[0]) 可以作为解决方案吗?

最佳答案

我想出了一个更快的coo对角线:

msk = M.row==M.col
D1 = sparse.coo_matrix((M.data[msk],(M.row[msk],M.col[msk])),shape=M.shape)

sparse.tril 将此方法与 mask = A.row + k >= A.col (sparse/extract.py) 结合使用

有时为 (100,100) M (并且 M1 = M.tocsr())

In [303]: timeit msk=M.row==M.col; D1=sparse.coo_matrix((M.data[msk],(M.row[msk],M.col[msk])),shape=M.shape)
10000 loops, best of 3: 115 µs per loop

In [305]: timeit D=sparse.diags(M.diagonal(),0)
1000 loops, best of 3: 358 µs per loop

因此,获取对角线的 coo 方法很快,至少对于这个小且非常稀疏的矩阵(对角线仅出现 1 次)

如果我从 csr 表单开始,diags 会更快。这是因为 .diagonalcsr 格式工作:

In [306]: timeit D=sparse.diags(M1.diagonal(),0)
10000 loops, best of 3: 176 µs per loop

但是创建D只是整个计算的一小部分。同样,使用 M1 速度更快。总和以 csr 格式完成。

In [307]: timeit M+M.T-D
1000 loops, best of 3: 1.35 ms per loop

In [308]: timeit M1+M1.T-D
1000 loops, best of 3: 1.11 ms per loop
<小时/>

完成整个事情的另一种方法是利用 coo 允许重复的 i,j 值,这些值在转换为 时将被求和csr 格式。因此,您可以将 Mrow、col、data 数组与 M.T 的数组堆叠在一起(请参阅 M.transpose了解它们的构造方式),以及 D 的掩码值。 (或者可以从 MM.T 中删除屏蔽对角线)

例如:

def MplusMT(M):
    msk=M.row!=M.col;
    data=np.concatenate([M.data, M.data[msk]])
    rows=np.concatenate([M.row, M.col[msk]])
    cols=np.concatenate([M.col, M.row[msk]])
    MM=sparse.coo_matrix((data, (rows, cols)), shape=M.shape)
    return MM

# alt version with a more explicit D
#    msk=M.row==M.col;
#    data=np.concatenate([M.data, M.data,-M.data[msk]])

MplusMT 编写的速度非常快,因为它只是进行数组串联,而不是求和。为此,我们必须将其转换为 csr 矩阵。

MplusMT(M).tocsr() 

这需要相当长的时间。不过,在我有限的测试中,这种方法比 M+M.T-D 快 2 倍以上。因此它是构建复杂稀疏矩阵的潜在工具。

关于python - 从稀疏 coo_matrix 获得的对角稀疏矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27950827/

相关文章:

python - 使用 SQLAlchemy Core 选择多行中的第一行

python - 尝试使用 scipy 将三角函数拟合到数据

numpy - 创建 A.T * diag(b) * A + C 形式的稀疏矩阵的最快方法?

matlab - 在 MATLAB 中按向量的元素缩放稀疏矩阵中的每一行

python - str在Python中是如何实现的?

python - 如何一次将二维数组的两列与python中另一个数组的列进行比较

matlab - 解决*稀疏*上三角系统

C++ Armadillo 稀疏矩阵类型转换

python - 正则表达式选择性地包含分隔符

python - numpy cov(协方差)函数,它到底计算什么?