Самый эффективный способ подстановки разреженной матрицы - PullRequest
0 голосов
/ 20 сентября 2019

У меня есть две большие, разреженные матрицы одного размера, одна из которых с фиктивными (0/1), и мне нужно вычислить их произведение Адамара (поэлементное умножение):

density = 40000000
rows = 1500000
cols = 1000
a = sparse.csr_matrix(sparse.coo_matrix((np.random.random_sample((density,)),
                                        (np.random.choice(np.arange(rows), density), 
                                         np.random.choice(np.arange(cols), density))), 
                                          shape=(rows,cols)))
b = sparse.csr_matrix(sparse.coo_matrix((np.random.choice(np.arange(2), density),
                                        (np.random.choice(np.arange(rows), density), 
                                         np.random.choice(np.arange(cols), density))), 
                                          shape=(rows,cols)))

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

В отличие от умножения ..

a.multiply(b)

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

array([[0.94510061, 0.10967919, 0.29398388],              array([[0., 0., 1.],            array([[0., 0., 0.29398388],
       [0.94510061, 0.10967919, 0.29398388],                     [0., 0., 1.],                   [0., 0., 0.29398388],
       [0.94510061, 0.10967919, 0.29398388],      x              [0., 1., 0.],    =              [0., 0.10967919, 0.],   
       [0.41112772, 0.94716107, 0.2308533 ],                     [1., 0., 0.],                   [0.41112772, 0., 0.],
       [0.41112772, 0.94716107, 0.2308533 ]])                    [0., 1., 0.]])                  [0., 0.94716107, 0.]])

Для этого я разрезаю матрицу a, как показано ниже, которая оказывается очень трудоемкой (после этого планировалось поместить vals в новый coo_matrix с такими же координатами).

nz = sparse.csr_matrix.nonzero(b)
vals = a[nz[0], nz[1]]

В1: Есть ли более эффективный способ нарезать разреженную матрицу?

Я знаю, что плотная a (a.A[nz[0], nz[1]]) нарезана намного быстрее, но затем затраты на преобразование его в плотное превосходит цель того, чего я пытаюсь достичь.

Кроме того, я прочитал еще один вопрос SO, пытаясь достичь противоположности (т. Е. Эффективного разрезания разреженной матрицы), что наилучшим способом может быть умножение на фиктивную, что не очень обнадеживает в отношениимоя проблема.Итак, Q2, если кто-то может придумать лучшее решение, чем то, которое я пытаюсь реализовать, было бы более чем приветствуем .

...