2015-06-25 3 views
1

Скажем, у меня есть Numpy массив p и SciPy разреженную матрицу q таким образом, чтоDot продукта между 1D Numpy массива и SciPy разреженная матрица

>>> p.shape 
(10,) 
>>> q.shape 
(10,100) 

Я хочу сделать скалярное произведение р и д. Когда я пытаюсь с NumPy я получаю следующее:

>>> np.dot(p,q) 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/dist packages/IPython/core/interactiveshell.py", line 2883, in run_code 
    exec(code_obj, self.user_global_ns, self.user_ns) 
    File "<ipython-input-96-8260c6752ee5>", line 1, in <module> 
    np.dot(p,q) 
ValueError: Cannot find a common data type. 

я вижу в том, что Scipy documentation

По NumPy 1,7, np.dot не знает разреженных матриц, поэтому используя это приведет по неожиданным результатам или ошибкам. Вместо этого должна быть получена соответствующая плотная матрица

Но это наносит ущерб моей цели использования разреженной матрицы. Soooo, как мне делать точечные продукты между разреженной матрицей и массивом 1D numpy (матрица numpy, я открыт для обоих), не теряя разреженности моей матрицы?

Я использую Numpy 1.8.2 и Scipy 0.15.1.

ответ

4

Использование *:

p * q 

Обратите внимание, что * использует матрицу типа семантики, а не массив типа семантики для разреженных матриц, поэтому он вычисляет произведение матриц, а не транслируемый продукта.

+1

И помните о предстоящем умножении @ для mATtrix https://www.python.org/dev/peps/pep-0465/ –

1

Scipy имеет встроенные методы для разреженного умножения матрицы.

Пример из документации:

>>> import numpy as np 
>>> from scipy.sparse import csr_matrix 
>>> Q = csr_matrix([[1, 2, 0], [0, 0, 3], [4, 0, 5]]) 
>>> p = np.array([1, 0, -1]) 
>>> Q.dot(p) 
array([ 1, -3, -1], dtype=int64) 

Проверьте эти ресурсы:

http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.csc_matrix.dot.html http://docs.scipy.org/doc/scipy/reference/sparse.html

+1

Это не так удобно, когда q находится справа от продукта. – user2357112

+0

В этом случае q сам может быть выполнен как csr_matrix. Я попробую... – Aditya

2

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

По многочисленным просьбам, последние np.dot редко осведомлены, хотя я не знаю подробностей о том, как он действует на это. В 1.18 мы имеем несколько вариантов.

user2357112 предлагает p*q. Вначале с плотным массивом я немного сомневался, задаваясь вопросом, будет ли он пытаться использовать элемент массива путем умножения элементов (и сбой из-за ошибок вещания). Но это работает. Иногда операторы вроде * передают управление второму аргументу. Но для того, чтобы быть уверенным, я попробовал несколько альтернатив:

q.T * p 
np.dot(p, q.A) 
q.T.dot(p) 

все дают одинаковый плотный (100,) массив. Примечание. Это массив, а не разреженный результат матрицы.

Чтобы получить разреженную матрицу Мне нужно использовать

sparse.csr_matrix(p)*q # (1,100) shape 

q могут быть и другие редкие форматы, но для расчетов, как это он преобразуется в csr или csc. И .T операция дешевая, потому что, если просто требуется переключение формата от csr до csc.

Было бы неплохо проверить, работают ли эти альтернативы, если p является 2-мерным массивом, например. (2,10).

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