矩阵运算中numpy中数组类和矩阵类之间的差异

时间:2017-01-25 10:34:07

标签: python arrays matlab numpy

我正在尝试使用Numpy进行矩阵点积和转置,我发现数组可以做矩阵可以做的很多事情,比如点积,点积和转置。

当我必须创建矩阵时,我必须先创建一个数组。

示例:

import numpy as np

array = np.ones([3,1]) 

matrix = np.matrix(array)

由于我可以在数组类型中进行矩阵转置和点积,所以我不必将数组转换为矩阵来进行矩阵运算。

例如,以下行有效,其中A是 ndarray

dot_product = np.dot(A.T, A ) 

先前的矩阵运算可以用矩阵类变量A

表示
dot_product = A.T * A  

运算符*与ndarray的逐点乘积完全相同。因此,它使 ndarray 矩阵几乎无法区分并导致混淆。

REP465

所述,混乱是一个严重的问题
  

使用numpy.matrix编写代码也可以正常工作。但麻烦开始了   我们试图将这两段代码整合在一起。码   期望ndarray并获得矩阵,反之亦然,可能会崩溃或   返回错误的结果。跟踪哪些功能期望   哪些类型作为输入,并返回哪些类型作为输出,然后   一直来回转换,是非常繁琐的   不可能以任何规模做对。

如果我们坚持使用 ndarray 并弃用矩阵并使用矩阵运算方法支持ndarray,例如.inverse(),. hermitian(),outerproduct,那将是非常诱人的()等,将来。

我仍然需要使用 matrix 类的主要原因是它将1d数组作为2d数组处理,所以我可以转置它。

到目前为止,我转换1d数组是非常不方便的,因为大小为n的1d数组具有形状(n,)而不是(1,n)。例如,如果我必须做两个数组的内积:

A = [[1,1,1],[2,2,2].[3,3,3]] 

B = [[1,2,3],[1,2,3],[1,2,3]]

np.dot(A,B)工作正常,但如果

B = [1,1,1] 

,它的转置仍然是行向量。

当输入变量的维度未知时,我必须处理此异常。

我希望这能帮助一些有同样问题的人,并希望知道是否有更好的方法来处理像Matlab中的矩阵操作,尤其是1d数组。感谢。

1 个答案:

答案 0 :(得分:3)

您的第一个示例是列向量:

In [258]: x = np.arange(3).reshape(3,1)
In [259]: x
Out[259]: 
array([[0],
       [1],
       [2]])
In [260]: xm = np.matrix(x)

dot产生内积,尺寸如下:(1,2),(2,1)=>(1,1)

In [261]: np.dot(x.T, x)
Out[261]: array([[5]])

矩阵产品做同样的事情:

In [262]: xm.T * xm
Out[262]: matrix([[5]])

(与1d数组相同的是产生标量值np.dot([0,1,2],[0,1,2]) # 5

数组的元素乘法产生外部产品(np.outer(x, x)np.dot(x,x.T)

也是如此
In [263]: x.T * x
Out[263]: 
array([[0, 0, 0],
       [0, 1, 2],
       [0, 2, 4]])

对于ndarray*是元素乘法(MATLAB的.*,但添加了广播)。对于matrix使用np.multiply(xm,xm)的元素乘法。 (scipy稀疏矩阵有一个乘法,X.multiply(other)

您引用了添加了@运算符(matmul)的PEP。这个,以及np.tensordotnp.einsum可以处理更大的维度数组和其他产品组合。那些不适用于np.matrix,因为它仅限于2d。

使用3x3 AB

In [273]: np.dot(A,B)
Out[273]: 
array([[ 3,  6,  9],
       [ 6, 12, 18],
       [ 9, 18, 27]])
In [274]: C=np.array([1,1,1])
In [281]: np.dot(A,np.array([1,1,1]))
Out[281]: array([3, 6, 9])

有效地将每一行加起来。 np.dot(A,np.array([1,1,1])[:,None])执行相同的操作,但返回一个(3,1)数组。

几年前创建的

np.matrix使numpy(实际上是其前身之一)感觉更像MATLAB。一个关键特征是它仅限于2d。这就是20世纪90年代MATLAB的样子。 np.matrix和MATLAB没有1d数组;相反,他们有单列或单行矩阵。

如果ndarrays可能是1d(甚至0d)的事实是个问题,那么添加第二维的方法有很多种。我更喜欢[None,:]种语法,但reshape也很有用。 ndmin=2np.atleast_2dnp.expand_dims也有效。

np.sum以及其他减少尺寸的操作都有一个keepdims=True参数来对付它。新的@给出了矩阵乘法的运算符语法。据我所知,np.matrix类没有自己的任何编译代码。

============

*实施np.matrix的方法使用np.dot

 def __mul__(self, other):
    if isinstance(other, (N.ndarray, list, tuple)) :
        # This promotes 1-D vectors to row vectors
        return N.dot(self, asmatrix(other))
    if isscalar(other) or not hasattr(other, '__rmul__') :
        return N.dot(self, other)
    return NotImplemented