我想知道最好的方法是编写可以处理稀疏和密集矩阵的代码。以下示例显示了我的关注:
输入:
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)
输出:
(1, 2) (2,)
从数学角度看,第一个结果似乎是错误的。将结果提供给需要向量的函数会产生错误。我可以将输出转换为数组并进行压缩:
print(np.asarray(A.dot(x)).squeeze().shape)
(2,)
这是最好的解决方案吗?
答案 0 :(得分:1)
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,)。但是值得记住的是,当一个或另一个输入为1d时,dot
有一些特殊的规则。
纯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
处理不适用。 (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
是最干净的。但这实际上取决于您想要哪种输出。