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

Fast insertion of sparse matrix into an other one

我想知道 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 的建议持开放态度。 谢谢

这是一种矢量化方法,利用加法和乘法的特性,并使用 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