Быстрая вставка разреженной матрицы в другую - PullRequest
1 голос
/ 18 октября 2019

Я хотел бы знать, есть ли в 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 Ответ

3 голосов
/ 18 октября 2019

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