Как поэлементно умножить матрицу scipy.sparse на транслируемый плотный 1d массив?

Предположим, у меня есть 2d разреженный массив. В моем реальном случае использования число строк и столбцов намного больше (скажем, 20000 и 50000), поэтому оно не может поместиться в памяти при использовании плотного представления:

>>> import numpy as np
>>> import scipy.sparse as ssp

>>> a = ssp.lil_matrix((5, 3))
>>> a[1, 2] = -1
>>> a[4, 1] = 2
>>> a.todense()
matrix([[ 0.,  0.,  0.],
        [ 0.,  0., -1.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  2.,  0.]])

Теперь предположим, что у меня есть плотный массив 1d со всеми компонентами, не равными нулю, размером 3 (или 50000 в моем случае из реальной жизни):

>>> d = np.ones(3) * 3
>>> d
array([ 3.,  3.,  3.])

Я хотел бы вычислить поэлементное умножение a и d, используя обычную семантику широковещания numpy. Однако разреженные матрицы в scipy принадлежат np.matrix: оператор '*' перегружен, чтобы он вел себя как матричное умножение вместо поэлементного умножения:

>>> a * d
array([ 0., -3.,  0.,  0.,  6.])

Одним из решений было бы переключение семантики массива для оператора '*', что дало бы ожидаемый результат:

>>> a.toarray() * d
array([[ 0.,  0.,  0.],
       [ 0.,  0., -3.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  6.,  0.]])

Но я не могу этого сделать, поскольку вызов toarray () материализует плотную версию 'a', которая не помещается в памяти (и результат также будет плотным):

>>> ssp.issparse(a.toarray())
False

Любая идея, как построить это, сохраняя только разреженные структуры данных и не делая неэффективный цикл Python для столбцов «а»?

Ответы на вопрос(3)

Ваш ответ на вопрос