Python 使矩阵乘法运算符@适用于numpy中的标量

Python 使矩阵乘法运算符@适用于numpy中的标量,python,numpy,signal-processing,linear-algebra,matrix-multiplication,Python,Numpy,Signal Processing,Linear Algebra,Matrix Multiplication,在python 3.5中,为矩阵乘法引入了@运算符,如下所示。例如,在numpy中,这是作为 但是,正如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

在python 3.5中,为矩阵乘法引入了
@
运算符,如下所示。例如,在numpy中,这是作为

但是,正如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'
>>将numpy作为np导入
>>>np.array([[1,2],[3,4]])@np.array([[1,2],[3,4]])#有效
数组([[7,10],
[15, 22]])
>>>1@2#不起作用
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:不支持@:'int'和'int'的操作数类型
这对我来说真是一件令人讨厌的事,因为我正在实现数字信号处理算法,它应该同时适用于标量和矩阵。这两种情况下的方程在数学上完全等价,这并不奇怪,因为“1-D x 1-D矩阵乘法”等价于标量乘法。但是,当前状态迫使我编写重复的代码,以便正确处理这两种情况

因此,考虑到当前状态并不令人满意,是否有任何合理的方法可以使
@
操作符为标量工作?我曾考虑过向标量数据类型添加一个自定义的
\uuu matmul\uuu(self,other)
方法,但考虑到涉及的内部数据类型的数量,这似乎有很多麻烦。我是否可以更改numpy数组数据类型的
\uuuu matmul\uuuu
方法的实现,使其不引发1x1数组操作数的异常

另外,这一设计决策背后的基本原理是什么?在我脑海中,我想不出任何令人信服的理由不也为标量实现该运算符。

正如建议的那样,您可以通过在相乘的对象上强制一些最小维度来解决这个问题。有两个合理的选项:and对于
@
返回的类型有不同的结果:标量和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是1D数组,则至少使用_2d会导致错误,否则会正常相乘
  • 至少使用_1d将生成标量或矩阵的乘积,而您不知道是哪个
  • 这两种方法都比np.dot(x,y)更详细,后者可以处理所有这些情况

此外,至少_1d版本还存在同样的缺陷,如果使用scalar@scalar=scalar,也会有同样的缺陷:您不知道如何处理输出。
z.T
z.shape
会抛出错误吗?它们适用于1乘1矩阵,但不适用于标量。在Python的设置中,如果不放弃标量和1乘1数组所具有的所有方法和属性,就不能忽略标量和1乘1数组之间的区别

[1]@[2]
怎么样?标量已经有了
*
,那么为什么要复制它呢。听起来真正的问题是你的代码有时返回标量,有时返回矩阵。为什么不重构,让代码返回1 x 1矩阵而不是标量?或者编写一个快速函数,获取一个矩阵或标量,并返回该矩阵或带有itAs标量的1x1矩阵,以说明从链接的PEP中:
0d(标量)输入引发错误的原因。标量*矩阵乘法在数学和算法上与矩阵@矩阵乘法不同,并且已包含在elementwise*运算符中。因此,允许标量@matrix既需要一个不必要的特殊情况,又违反了TOOWTDI。
当我写
[1]@[2]
时,我在考虑类似
np.array([1])@np.array([2])
的东西,但我应该描述一下:)也许你可以使用
至少1d
,例如
np至少1d(5)@np至少1d(6)
工作正常。