我知道我可以使用.dot
语法使用numpy数组进行矩阵乘法。常规的CCD_ 2乘法进行逐元素乘法。
a = np.array([[1,2],[3,4]])
print 'matrix multiplication', a.dot(a)
print 'element-wise multiplication', a * a
> matrix multiplication [[ 7 10] [15 22]]
> element-wise multiplication [[ 1 4] [ 9 16]]
这很好,但它与我所学的所有矩阵运算相反(即,"点积"通常是逐元素的,而正则积通常是全矩阵乘法。(
所以我正在调查np.matrix
。好处是矩阵乘法使用了*
运算符,但我要了解如何进行元素乘法。
m = np.matrix(a)
print 'matrix multiplication', m * m
print 'more matrix multiplication? ', m.dot(m)
> matrix multiplication [[ 7 10] [15 22]]
> more matrix multiplication? [[ 7 10] [15 22]]
我理解发生了什么——numpy矩阵没有.dot
运算符,所以它可以实现为基本的np.array
。但这是否意味着无法使用np.matrix
计算点积?
这只是避免np.matrix
而坚持使用np.array
的另一个论点吗?
您可以使用multiply
函数获得元素乘法:
>>> np.multiply(m, m)
matrix([[ 1, 4],
[ 9, 16]])
结果与CCD_ 11相同。
dot
这个名称确实有点误导,但np.dot
的文档清楚地说:"对于二维数组,它相当于矩阵乘法"。严格地说,点积不是为矩阵定义的;元素乘法将是弗罗贝尼乌斯的内积。
向量的np.dot
与dot product
(也称为标量积(一致
In [125]: np.arange(10).dot(np.arange(1,11))
Out[125]: 330
但CCD_ 16被推广用于2维(及更高维(阵列。
MATLAB从一开始就建立在二维矩阵上,矩阵乘积被视为最常见和最基本的乘法。因此,.*
表示法被用于逐元素乘法。CCD_ 18也可以与CCD_ 19和其他运算符一起使用。
CCD_ 20的基本结构是一个n-d阵列。由于这样的数组可以有0,1,2或更多的维度,因此数学运算符被设计为按元素工作。提供CCD_ 21来处理矩阵乘积。有一种变体叫做*
2。np.einsum
使用爱因斯坦符号(在物理学中很流行(。一个新的@
操作符调用np.matmul
函数
In [131]: a.dot(a)
Out[131]:
array([[ 7, 10],
[15, 22]])
In [134]: np.einsum('ij,jk->ik',a,a)
Out[134]:
array([[ 7, 10],
[15, 22]])
In [135]: a@a
Out[135]:
array([[ 7, 10],
[15, 22]])
In [136]: np.matmul(a,a)
Out[136]:
array([[ 7, 10],
[15, 22]])
np.matrix
是ndarray
的一个子类,添加它是为了让任性的MATLAB用户更熟悉numpy
。就像旧版本的MATLAB一样,它只能是二维的。所以CCD_ 29的计算结果将始终是2d(或标量(。它的使用通常是不鼓励的,尽管我相信它会存在很长一段时间。(与np.matrix
相比,我更多地使用sparse
矩阵(。
添加了@
运算符后,使用np.matrix
的理由就少了一个。
In [149]: m=np.matrix(a)
In [150]: m*m
Out[150]:
matrix([[ 7, 10],
[15, 22]])
In [151]: m@m
Out[151]:
matrix([[ 7, 10],
[15, 22]])
In [152]: m*m*m
Out[152]:
matrix([[ 37, 54],
[ 81, 118]])
In [153]: a@a@a
Out[153]:
array([[ 37, 54],
[ 81, 118]])