Умножение матриц: поддержка формата scipy.sparse.dok_matrix - PullRequest
0 голосов
/ 20 октября 2019

Я пытаюсь использовать scipy для выполнения разреженных вычислений линейной алгебры в формате dok (словарь ключей). Когда я умножаю две матрицы вместе, формат меняется с типа док на формат CSR, который является неэффективным форматом для данных и последующих операций.

Как мне сохранить формат dok?

Я просмотрел документы:

Но не видно никакой информации автоматического преобразования типа или если и как его можно избежать.

См. Этот пример:

from scipy.sparse import dok_matrix

my_mat = dok_matrix([[1,2], [3,4]])

print(type(my_mat.dot(my_mat)))
print(type(my_mat @ my_mat))

показывает, что формат был изменен:

<class 'scipy.sparse.csr.csr_matrix'>
<class 'scipy.sparse.csr.csr_matrix'>

Ответы [ 2 ]

0 голосов
/ 20 октября 2019

Как указывает @ user2357112 csr подходит для линейной алгебры. Однако стоимость конверсии значительна. Поскольку dok - не единственный формат, который поддерживает редактирование приемлемого времени, стоит проверить другой вариант, который lil. В зависимости от вашего варианта использования вы можете сэкономить немного времени:

from scipy import sparse
from timeit import timeit

a = random(100,100,0.1,format='lil')
b = random(100,100,0.1,format='dok')
a
# <100x100 sparse matrix of type '<class 'numpy.float64'>'
#         with 1000 stored elements in LInked List format>
b
# <100x100 sparse matrix of type '<class 'numpy.float64'>'
#         with 1000 stored elements in Dictionary Of Keys format>
timeit(lambda:(a@a).tolil(),number=100)*10
# 1.491789099527523
timeit(lambda:(b@b).todok(),number=100)*10
# 4.220661079743877

Обратите внимание, что a@a / b@b довольно плотно в этом примере, если мы выбираем более редкий вариант, разница менее выражена:

a = random(100,100,0.01,format='lil')
b = random(100,100,0.01,format='dok')

timeit(lambda:(a@a).tolil(),number=100)*10
# 0.6880075298249722
timeit(lambda:(b@b).todok(),number=100)*10
# 0.7450748200062662
0 голосов
/ 20 октября 2019

Просто конвертируйте обратно:

result = result.todok()

CSR может быть неэффективным форматом для последующих операций (или, может быть, нет, мы не можем сказать), но он отлично подходит для умножения матриц. Попытка заставить код умножения матриц работать с результатом DOK изначально будет медленнее, чем просто преобразование результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...