在python 3.5中,在PEP465之后引入了@运算符用于矩阵乘法。例如,在numpy中,这被实现为matmul operator
但是,正如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'

这是一个真正的岔路,因为我正在实施数字信号处理算法,应该为标量和矩阵。这两种情况的方程在数学上是完全等价的,这并不奇怪,因为“1-D×1-D矩阵乘法”等价于标量乘法。但是,当前状态迫使我编写重复的代码,以便正确处理这两种情况。
因此,考虑到当前状态不令人满意,是否有任何合理的方法可以使@操作符为标量工作?我考虑过向标量数据类型添加一个定制的__matmul__(self, other)方法,但是考虑到涉及的内部数据类型的数量,这看起来很麻烦。是否可以更改对NUPY数组数据类型的__matmul__方法的实现,而不为1x1数组操作数抛出异常?
另外,还有一点需要说明的是,这个设计决策背后的基本原理是什么?在我的脑海中,我想不出任何有说服力的理由不为标量实现这个操作符。

最佳答案

正如ajcr所建议的,您可以通过在被乘对象上强制一些最小维度来解决这个问题。有两个合理的选项:atleast_1datleast_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]])

然而:
如果x和y是通常相乘的一维数组,使用至少2d将导致错误
使用至少1d会得到标量或矩阵的乘积,而您不知道是哪一个。
这两种方法都比处理所有这些情况的np.dot(x, y)更详细。
同样,ATLASTAS1D版本遭受同样的缺陷,它也会被标量@标量=标量共享:你不知道用输出可以做什么。是否会引发错误?这些方法适用于1乘1矩阵,但不适用于标量。在python的设置中,如果不放弃scalar和1乘1数组的所有方法和属性,就不能忽略它们之间的区别。

关于python - 使矩阵乘法运算符@对numpy中的标量有效,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41186356/

10-13 05:23