numpy.array的/ =运算符有奇怪的行为吗?

问题描述

我正在尝试将数字数组规范化为范围(0,1],以便可以将它们用作加权的random.choice()的权重,所以我输入了这一行:

# weights is a nonzero numpy.array
weights /= weights.max()

但是,Pycharm表示max()函数Parameter 'initial' unfilled)有一个未填充的参数。我在REPL中使用/ =运算符并使用“常规”除法(a = a / b)对此进行了尝试,但两者均得到了不同的结果,并且得到了与Pycharm所认为的不同的错误

>>> a = numpy.array([1,2,3])
>>> a.max()
3
>>> a /= a.max()
Traceback (most recent call last):
  File "<pyshell#4>",line 1,in <module>
    a /= a.max()
TypeError: No loop matching the specified signature and casting was found for ufunc true_divide
>>> a = a/a.max()
>>> a
array([0.33333333,0.66666667,1.        ])

我还意识到,对于加权随机数, sum 需要权重而不是对其进行归一化。但是用/ =运算将其除以总和即可得到完全相同的TypeError(但Pycharm认为这样做还可以):

>>> a = numpy.array([1,3])
>>> sum(a)
6
>>> a
array([1,3])
>>> a /= sum(a)
Traceback (most recent call last):
  File "<pyshell#13>",in <module>
    a /= sum(a)
TypeError: No loop matching the specified signature and casting was found for ufunc true_divide
>>> a = a / sum(a)
>>> a
array([0.16666667,0.33333333,0.5       ])

在这里遇到了什么?这是Numpy中的一个怪异错误,还是/ =运算符有其他用途或其他用途?我知道他们使用__truediv____itruediv__,但我看不出为什么一个有问题而另一个没有。我已通过pip的最新版本的Numpy(在Windows x64上为1.19.2)确认了此行为。

解决方法

这是因为numpy关心类型。应用除法时,您正在将int更改为float。但是Numpy不会让你这样做!这就是为什么您的值应该已经在float中的原因。试试这个:

>>> a = np.array([1.0,2.0,3.0])
>>> a /= sum(a)
>>> a
array([0.16666667,0.33333333,0.5       ])

但是另一个为什么起作用?这是因为这不是“就地”操作。因此,正在创建一个新的存储位置。新变量,新类型,因此numpy不在这里。