python – numpy矩阵代数最佳实践
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – numpy矩阵代数最佳实践,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4508字,纯文字阅读大概需要7分钟。
内容图文
![python – numpy矩阵代数最佳实践](/upload/InfoBanner/zyjiaocheng/789/06b90796dd8c4da284fda739f33b3037.jpg)
我的问题是关于下面的最后一行:mu @ sigma @ mu.它为什么有效?将一维ndarray视为行向量还是列向量?无论哪种方式,不应该是mu.T @ sigma @ mu或mu @ sigma @ mu.T?我知道mu.T仍然返回mu,因为mu只有一个维度,但是,解释器似乎太聪明了.
>> import numpy as np
>> mu = np.array([1, 1])
>> print(mu)
[1 1]
>> sigma = np.eye(2) * 3
>> print(sigma)
[[ 3. 0.]
[ 0. 3.]]
>> mu@sigma@mu
6.0
更一般地说,这是python中矩阵代数的一种更好的实践:使用ndarray和@进行上面的矩阵乘法(更干净的代码),或者使用np.matrix和下面的重载*(数学上不那么混乱)
>> import numpy as np
>> mu = np.matrix(np.array([1, 1]))
>> print(mu)
[[1 1]]
>> sigma = np.matrix(np.eye(2) * 3)
>> print(sigma)
[[ 3. 0.]
[ 0. 3.]]
>> a = mu * sigma * mu.T
>> a.item((0, 0))
6.0
解决方法:
Python从左到右执行链式操作:
In [32]: mu=np.array([1,1])
In [33]: sigma= np.array([[3,0],[0,3]])
In [34]: mu@sigma@mu
Out[34]: 6
与做两个表达式相同:
In [35]: temp=mu@sigma
In [36]: temp.shape
Out[36]: (2,)
In [37]: temp@mu
Out[37]: 6
在我的评论(删除)中,我声称@只是在做np.dot.那不太对劲.该文档描述了不同的1d数组的处理.但结果形状是相同的:
In [38]: mu.dot(sigma).dot(mu)
Out[38]: 6
In [39]: mu.dot(sigma).shape
Out[39]: (2,)
对于1d和2d数组,np.dot和@应该产生相同的结果.它们在处理高维数组时有所不同.
历史上numpy使用的数组可以是0d,1d和on. np.dot是原始矩阵乘法方法/函数.
添加了np.matrix,主要是为了方便任性的MATLAB程序员.它只允许2d数组(就像旧的,20世纪90年代的MATLAB一样).并且它会重载__mat __(*)
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
Mu * sigma和Mu @ sigma表现相同,尽管调用树是不同的
In [48]: Mu@sigma@Mu
...
ValueError: shapes (1,2) and (1,2) not aligned: 2 (dim 1) != 1 (dim 0)
Mu * sigma产生一个(1,2)矩阵,它不能矩阵乘以a(1,2),因此需要转置:
In [49]: Mu@sigma@Mu.T
Out[49]: matrix([[6]])
注意,这是(1,1)矩阵.如果你想要一个标量,你必须使用item. (在MATLAB中没有标量这样的东西.一切都有形状/大小.)
@是Python和numpy的最新成员.它作为未实现的运算符添加到Python中. numpy(可能还有其他包)实现了它.
它使得链式表达式成为可能,尽管我对[38]中的链式点没有任何问题.在处理更高维度的情况时,它更有用.
这个添加意味着使用旧的np.matrix类的原因就更少了. (类似行为的行为在scipy.sparse矩阵类中根深蒂固.)
如果你想要“数学纯度”,我建议采用数学物理学方法,并使用爱因斯坦符号 – 在np.einsum中实现.
对于这么小的数组,时序反映了调用结构比实际计算数量更多:
In [57]: timeit mu.dot(sigma).dot(mu)
2.79 μs ± 7.75 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [58]: timeit mu@sigma@mu
6.29 μs ± 31.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [59]: timeit Mu@sigma@Mu.T
17.1 μs ± 134 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [60]: timeit Mu*sigma*Mu.T
17.7 μs ± 517 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
请注意,“老式”点是最快的,而两个矩阵版本都较慢.
在转置
我可以在mu @ sigma @ mu.T这样的表达式中添加它,首先评估.T,所以@(matmul)不知道有转换mu的尝试.它只是使用转置的结果.记住它是解析表达式的Python解释器,而不是numpy函数.因此,如果mu.T对mu没有任何作用,就像1d数组那样,.T对@也没有影响.
转置是为2d数组定义的. numpy转置的编写方式使得它也适用于任何维度的数组.它改变了轴的顺序,但从不添加尺寸.还有其他工具可以做到这一点,例如重塑和np.newaxis索引.
在Octave中,转置仅针对二维对象定义
>> ones(2,3,4)'
error: transpose not defined for N-d objects
MATLAB中不存在1-D对象.
In [270]: np.ones((2,3,4),int).T.shape
Out[270]: (4, 3, 2)
内外产品
np.dot非常清楚它如何处理1d数组,’vectors’:
- If both
a
andb
are 1-D arrays, it is inner product of vectors
(without complex conjugation).
在matmul中,描述更复杂,但结果是相同的.
关于你的评论:
A = [1, 2] and B = [3, 5] being (2, ) ndarray, A@B could mean [1, 2] * [3, 5]’ = 13, or it could mean [1, 2]’ * [3, 5] = [[3, 5], [6, 10]]
采取numpy产品的各种方法是:
In [273]: A = np.array([1,2]); B = np.array([3,5])
元素乘法(.*在MATLAB中)
In [274]: A*B
Out[274]: array([ 3, 10])
内在产品
In [275]: A@B # same as np.dot(A,B)
Out[275]: 13
外产品
In [276]: np.outer(A,B)
Out[276]:
array([[ 3, 5],
[ 6, 10]])
获得内在产品的另一种方法:
In [278]: np.sum(A*B)
Out[278]: 13
用爱因斯坦符号(来自数学物理学),内在和外在:
In [280]: np.einsum('i,i',A,B)
Out[280]: array(13)
In [281]: np.einsum('i,j',A,B)
Out[281]:
array([[ 3, 5],
[ 6, 10]])
利用广播来获得外部
In [282]: A[:,None]*B[None,:]
Out[282]:
array([[ 3, 5],
[ 6, 10]])
您想要的[1,2]’在numpy中实现为A [:,None],将1d数组转换为列向量(2d).
在八十年代之后,Octave增加了广播.我不知道MATLAB是否已经发展到那么远.
内容总结
以上是互联网集市为您收集整理的python – numpy矩阵代数最佳实践全部内容,希望文章能够帮你解决python – numpy矩阵代数最佳实践所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。