Вот векторизованный подход, использующий свойства сложения и умножения и использующий 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