jhi*_*hin 6 python signal-processing numpy linear-algebra matrix-multiplication
在python 3.5中,在PEP465之后@引入了用于矩阵乘法的运算符。这例如在numpy中作为matmul运算符实现。
但是,按照PEP的建议,当用标量操作数调用numpy运算符时会引发异常:
>>> import numpy as np
>>> np.array([[1,2],[3,4]]) @ np.array([[1,2],[3,4]]) # works
array([[ 7, 10],
[15, 22]])
>>> 1 @ 2 # doesn't work
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: unsupported operand type(s) for @: 'int' and 'int'
Run Code Online (Sandbox Code Playgroud)
对我来说,这是一个真正的选择,因为我正在实现对标量和矩阵均适用的数字信号处理算法。两种情况下的方程在数学上都是完全等价的,这并不奇怪,因为“ 1-D x 1-D矩阵乘法”等效于标量乘法。但是,当前状态迫使我编写重复的代码,以便正确处理这两种情况。
因此,鉴于当前状态不令人满意,是否有任何合理的方法可以使@操作员使用标量?我曾考虑过向__matmul__(self, other)标量数据类型添加自定义方法,但是考虑到涉及的内部数据类型的数量,这似乎很麻烦。我可以更改__matmul__numpy数组数据类型的方法的实现,以不为1x1数组操作数抛出异常吗?
而且,在旁注中,此设计决定的依据是什么?我不由自主地想到,没有任何令人信服的理由也不要将这种运算符用于标量。
小智 10
正如ajcr所建议的,您可以通过对相乘的对象强制一些最小维度来解决此问题。有两个合理的选项:atleast_1d和atleast_2d,它们对于 所返回的类型有不同的结果@:标量与 1×1 2D 数组。
x = 3
y = 5
z = np.atleast_1d(x) @ np.atleast_1d(y) # returns 15
z = np.atleast_2d(x) @ np.atleast_2d(y) # returns array([[15]])
Run Code Online (Sandbox Code Playgroud)
然而:
np.dot(x, y)处理所有这些情况更详细。此外, atleast_1d 版本也存在同样的缺陷,标量 @ 标量 = 标量也会共享该缺陷:您不知道可以对输出做什么。会z.T或z.shape抛出错误吗?这些适用于 1×1 矩阵,但不适用于标量。在Python的设置中,我们根本不能忽略标量和1×1数组之间的区别,而不放弃后者所拥有的所有方法和属性。