Сохранить определенные элементы продукта с большой матрицей

#numpy #scipy #sparse-matrix

#numpy #scipy #разреженная матрица

Вопрос:

Мне нужно вычислить следующее матричное выражение: XT - Y и сохранить элементы, соответствующие только ненулевым элементам матрицы Y . Например, если:

 In [63]: X.dot(T.T) - Y
Out[63]: array([[ -6,  -2], [ -9, -12]])
In [64]: Y
Out[64]: array([[5, 0], [7, 8]])
  

Тогда результат должен быть [[-6, 0], [-9, -12]] .

X и T оба являются векторами. Проблема в том, что оба X.dot(T.T) и Y имеют большой размер (скажем 350 x 23 000 000 ), поэтому Y хранятся как a scipy.sparse.csc_matrix с примерно 200 миллионами значений. У меня недостаточно памяти для хранения промежуточного XT результата.

Конечно, можно перебирать все ненулевые элементы Y и вручную вычислять каждый элемент XT и затем вручную создавать результат csc_matrix . Результат будет иметь те же indices indptr атрибуты и, что и, Y и это заставляет меня думать, что должен быть более короткий или быстрый способ.

Комментарии:

1. В контексте numpy значение «вектор» может быть неоднозначным. Вы используете X.dot(T.T) для вычисления внешнего произведения X и T , поэтому я предполагаю X , что и T хранятся как 2D массивы numpy с формой (350, 1) и (23000000, 1) (а не как 1D массивы с формой (350,) и (23000000,) . Это правильно?

2. @WarrenWeckesser, исправьте.

Ответ №1:

Вот один из способов, которым вы могли бы это сделать.

Во-первых, некоторые примеры данных:

 In [75]: X.T
Out[75]: array([[1, 2, 3]])

In [76]: T.T
Out[76]: array([[2, 3, 5, 7]])

In [77]: Y
Out[77]: 
<3x4 sparse matrix of type '<type 'numpy.int64'>'
    with 5 stored elements in Compressed Sparse Column format>

In [78]: Y.A
Out[78]: 
array([[0, 0, 4, 5],
       [6, 0, 0, 7],
       [0, 8, 0, 0]])
  

Преобразование Y в формат COO (чтобы индексы строк и столбцов ненулевых данных были легко доступны):

 In [79]: C = Y.tocoo()
  

Вычислите эквивалент X.dot(T.T) - Y , но только для значений, Y отличных от нуля:

 In [80]: data = X[C.row,0]*T[C.col,0] - C.data

In [81]: data
Out[81]: array([-2,  1,  1,  2,  7])
  

Сравнить с полным вычислением:

 In [82]: X.dot(T.T) - Y
Out[82]: 
matrix([[ 2,  3,  1,  2],
        [-2,  6, 10,  7],
        [ 6,  1, 15, 21]])
  

Если вам нужен результат в матрице CSC, например Y :

 In [84]: D = csc_matrix((data, (C.row, C.col)), shape=C.shape)

In [85]: D
Out[85]: 
<3x4 sparse matrix of type '<type 'numpy.int64'>'
    with 5 stored elements in Compressed Sparse Column format>

In [86]: D.A
Out[86]: 
array([[ 0,  0,  1,  2],
       [-2,  0,  0,  7],
       [ 0,  1,  0,  0]])