Размеры матричного умножения - PullRequest
0 голосов
/ 26 августа 2018

Мне интересно, как лучше написать код, который может работать с разреженными и плотными матрицами.Следующий пример показывает мое беспокойство:

input:

A = np.asmatrix(np.ones((2,3)))
B = sps.csr_matrix(A)
x = np.ones(3)
print(A.dot(x).shape, B.dot(x).shape)

output:

(1, 2) (2,)

Первый результат кажется неверным с математической точки зрения.Передача результата функции, которая ожидает вектор, дает ошибку.Я мог бы преобразовать вывод в массив и сжать его:

print(np.asarray(A.dot(x)).squeeze().shape)
(2,)

Это лучшее решение?

1 Ответ

0 голосов
/ 26 августа 2018

плотность

In [135]: A.dot(x)
Out[135]: matrix([[3., 3.]])
In [136]: np.ones((2,3)).dot(x)
Out[136]: array([3., 3.])

np.matrix является подклассом ndarray, который должен быть 2d, и пытается, насколько это возможно, вернуть np.matrix (2d) результаты.Следовательно, Out[135] равно 2d (1,2).

Out[136], с другой стороны, является (2,3) точкой (3,) => (2,).Но стоит помнить, что dot имеет некоторые особые правила, когда один или другой из входов равен 1d.

Чистый np.matrix точка:

In [161]: A.dot(np.matrix(x).T)   # A*np.matrix(x).T
Out[161]: 
matrix([[3.],
        [3.]])

разреженный

Хотя матрица sparse смоделирована на np.matrix, она является собственным классом и во многих случаях ведет себя по-разному.dot разреженных и плотных может быть хитрым.

In [152]: B.shape
Out[152]: (2, 3)
In [153]: B.dot(x)
Out[153]: array([3., 3.])

Эффективно B был сначала преобразован в массив:

In [154]: B.A.dot(x)         # B.toarray()
Out[154]: array([3., 3.])

Но это неправильно, потому что он пытаетсяиспользовать np.array(B) вместо правильных B.toarray():

In [155]: np.dot(B,x)
Out[155]: 
array([<2x3 sparse matrix of type '<class 'numpy.float64'>'
    with 6 stored elements in Compressed Sparse Row format>,
       <2x3 sparse matrix of type '<class 'numpy.float64'>'
    with 6 stored elements in Compressed Sparse Row format>,
       <2x3 sparse matrix of type '<class 'numpy.float64'>'
    with 6 stored elements in Compressed Sparse Row format>], dtype=object)
In [156]: np.array(B)
Out[156]: 
array(<2x3 sparse matrix of type '<class 'numpy.float64'>'
    with 6 stored elements in Compressed Sparse Row format>, dtype=object)

Если обе переменные являются разреженными, то результат также является разреженным.В этом случае специальная обработка dot массивов 1d не применяется.A (2,3) должен умножить (3,1), чтобы получить (2,1):

In [158]: B*sparse.csr_matrix(x).T
Out[158]: 
<2x1 sparse matrix of type '<class 'numpy.float64'>'
    with 2 stored elements in Compressed Sparse Row format>
In [159]: _.A
Out[159]: 
array([[3.],
       [3.]])

В сумме типы смешивающих матриц могут сбивать с толку.Было бы чистейшим сначала преобразовать все в ndarray.Но это действительно зависит от того, какой вывод вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...