2016-10-29 10 views
0

В простом векторном умножении матрицы я получаю разные форматы результатов/вывода при использовании матрицы scipy.sparse вместо плотной матрицы. В качестве примера я использую следующую плотную матрицу и вектор:Разница между векторными матрицами между разреженной и плотной матрицей

import numpy as np 
from scipy import sparse 
mat = np.array([[1, 1, 0, 0, 0], [0, 2, 2, 0, 0], [0, 0, 3, 3, 0], [0, 0, 0, 4, 4]]) 
vec = np.arange(1, 5) 

Для векторного произведения матриц я получаю следующий ожидаемый результат:

vec.dot(mat) # array([ 1, 5, 13, 25, 16]) 
mat.T.dot(vec) # array([ 1, 5, 13, 25, 16]) 
mat.T.dot(vec.T) # array([ 1, 5, 13, 25, 16]) 

Я понимаю, что это не играет роли, если вектор транспонируется или нет. Но когда я заменить матрицу mat разреженной матрицей mat_sparse я получить в результате массив разреженных матриц 4x5, содержащих разреженную матрицу, умноженную на каждом компонент вектора, т.е. [1x mat_sparse, 2x mat_sparse, ...]

mat_sparse = sparse.lil_matrix(mat) 
vec.dot(mat_sparse) # array([ <4x5 sparse matrix of type '<type 'numpy.int64'>' with 8 stored elements in LInked List format>, ...], dtype=object) 

Использования транспонированной матрицы трюка я получаем ожидаемый результат:

mat_sparse.T.dot(vec4.T) # array([ 1, 5, 13, 25, 16]) 

Может кто-нибудь объяснить, почему это поведение ожидается/требуется? Замена матрицы mat (которая фактически представляет собой 2D-массив) экземпляром np.matrix(mat не изменяет результаты.

ответ

0

Как правило, не учитываются функции и методы numpy для правильной работы с разреженными матрицами. Лучше использовать редкие методы и функции. Обычный код numpy ничего не знает о разреженных матрицах.

С матрицей (разреженной или np.matrix), * является матричным умножением.

In [2150]: vec*smat # smat=csr_matrix(mat) 
Out[2150]: array([ 1, 5, 13, 25, 16], dtype=int32) 

В этом контексте разреженного определение матрицы * имеет преимущество.

In [2151]: vec.dot(smat) 
Out[2151]:... 
array([ <4x5 sparse matrix of type '<class 'numpy.int32'>' 
    with 8 stored elements in Compressed Sparse Row format>, 
    ... 
    with 8 stored elements in Compressed Sparse Row format>], dtype=object) 

В этом выражении vec.dot ничего о разреженных матрицы не знает. Сразу же кажется, что он выполняет dot отдельно с каждой строкой smat, но мне придется рыть дальше.

следующие работы, поскольку он использует разреженное определение dot, совпадает с его *:

In [2163]: smat.T.dot(vec) 
Out[2163]: array([ 1, 5, 13, 25, 16], dtype=int32) 

np.dot имеет ограниченное понимание разреженных матриц. Например, он работает, если оба аргумента разрежены. np.dot(smat, smat.T) работы (так же, как np.dot(mat, mat.T))

In [2177]: np.dot(smat.T,sparse.csr_matrix(vec).T).A 
Out[2177]: 
array([[ 1], 
     [ 5], 
     [13], 
     [25], 
     [16]], dtype=int32) 

Это может помочь, чтобы прочитать о том, как редкие матрицы создаются и хранят свои данные. Они не являются подклассами np.ndarray.

0

Результатом операций с матрицей sparse часто будет sparse матриц.

Если вы хотите преобразовать обратно в плотную матрицу, вам нужно попросить об этом, используя метод .toarray().

+0

При замене массива на матрицу, то есть с использованием 'mat2 = np.matrix (np.массив [[1, 1, 0, 0, 0], [0, 2, 2, 0, 0], [0, 0, 3, 3, 0], [0, 0, 0, 4, 4] ])) 'Я получаю матрицу ([[1, 5, 13, 25, 16]]). Поэтому я ожидал бы получить разреженную матрицу при использовании разреженной матрицы, но вместо этого получаю массив разреженных матриц. Использование 'todense()' в моем случае невозможно, так как я использую разреженные матрицы размером примерно 50000 x 50000. – murban

Смежные вопросы