快速将稀疏矩阵插入另一个

时间:2019-10-18 07:16:32

标签: python numpy scipy sparse-matrix

我想知道python中是否有更有效的方法来实现我的目标。我需要将一个稀疏矩阵(M2)插入另一个(M1)。两个稀疏矩阵都是csr

如果两个矩阵的值都在同一索引处,则M2覆盖M1。

目前我使用此代码:

N, M = 1000, 1000
M1 = sp.random(N,M,0.1,'csr')
M2 = sp.random(N,M,0.1,'csr')

def sparse_insert(M1, M2):
    """
    return the insertion of sparse matrix M2 into sparse matrix M1
    """
    out = M1.tolil()
    idxnnz, idynnz = M2.nonzero()
    for i, j in zip(idxnnz, idynnz):
        out[i, j] = M2[i, j]
    return out.tocsr()

M3 = sparse_insert(M1, M2)

我甚至愿意接受使用numba或cython的建议。 谢谢

1 个答案:

答案 0 :(得分:3)

这是一种利用加法和乘法属性并使用here中的divide_nonzero()的矢量化方法:

def divide_nonzero(a, b):
    inv_b = b.copy()
    inv_b.data = 1 / inv_b.data
    return a.multiply(inv_b)


def sparse_insert_vect(a, b):
    return a + b - divide_nonzero(a.multiply(b), b)

要检查结果是否与您相同:

import scipy as sp
import scipy.sparse

N, M = 1000, 1000
M1 = sp.sparse.random(N, M, 0.1, 'csr')
M2 = sp.sparse.random(N, M, 0.1, 'csr')


print(sp.all(sp.isclose(sparse_insert(M1, M2).data, sparse_insert_vect(M1, M2).data)))
# True

但时机要好得多

%timeit sparse_insert(M1, M2)
# 1 loop, best of 3: 1.84 s per loop
%timeit sparse_insert_vect(M1, M2)
# 100 loops, best of 3: 5.88 ms per loop