У меня есть две большие, разреженные матрицы одного размера, одна из которых с фиктивными (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, если кто-то может придумать лучшее решение, чем то, которое я пытаюсь реализовать, было бы более чем приветствуем .