假设我有Numpy数组p
和Scipy稀疏矩阵q
这样
>>> p.shape
(10,)
>>> q.shape
(10,100)
我想做一个p和q的点积。当我尝试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。
答案 0 :(得分:4)
使用*
:
p * q
请注意,*
对稀疏矩阵使用类似矩阵的语义而不是类似数组的语义,因此它计算矩阵乘积而不是广播产品。
答案 1 :(得分: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,10)。
答案 2 :(得分: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