矩阵与数组相乘的维数

时间:2018-08-26 16:50:17

标签: python numpy

我想知道最好的方法是编写可以处理稀疏和密集矩阵的代码。以下示例显示了我的关注:

输入:

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,)

这是最好的解决方案吗?

1 个答案:

答案 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.matrixndarray的子类,必须为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是最干净的。但这实际上取决于您想要哪种输出。