5

在这种情况下,为什么会x += y产生与 不同的结果x = x + y

import numpy as np

x = np.repeat([1], 10)
y = np.random.random(len(x))

x += y
print x
# Output: [1 1 1 1 1 1 1 1 1 1]

x = x + y
print x
# Output: [ 1.50859536  1.31434732  1.15147365  1.76979431  1.64727364
#           1.02372535  1.39335253  1.71878847  1.48823703  1.99458116]
4

2 回答 2

9

尽管链接的问题解释了一般问题,但对于这种特殊情况,有一个特定于 numpy 的解释。基本上,这些答案说“这取决于所涉及变量的类型”,而我在下面给出的是对 numpy 类型的解释。

当您这样做时x + y,numpy 使用“最小公分母”数据类型作为结果。由于x是 int 并且y是 float,这意味着它返回一个 float 数组。

但是当你这样做时x += y,你是在强迫它符合 dtype 的x,即int. 这会截断小数部分并将所有x值保留为 1。这是 numpy 定义增强赋值运算符的方式:它强制返回值与赋值目标具有相同的 dtype。

x = (x + y).astype(int)您可以通过执行(明确地将 dtype 强制返回 int)从第二个示例中获得第一个行为。您可以通过让从第一个示例中获得第二个行为x = np.repeat([1.0], 10)(使用浮点数使xdtype 具有浮点数,因此现在您可以在y不截断的情况下添加它)。

于 2013-06-21T06:30:23.700 回答
2

__add__由于和__iadd__方法之间的差异

然而,通常可以看出可变对象与不可变对象之间的差异

>>> x = np.repeat([1], 10)
>>> y = np.random.random(len(x))
>>> x += y
>>> x
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])

对比

>>> x = np.repeat([1.0], 10)
>>> x += y
>>> x
array([ 1.05192255,  1.00844068,  1.27569982,  1.40997015,  1.17270114,
        1.27335121,  1.70719855,  1.72778867,  1.64679031,  1.23241938])

当 x 是 int 类型时,__iadd__导致加法被截断回 int

如果您考虑一下,这是有道理的- x 不能神奇地更改其元素的类型(它将在哪里存储这些额外的字节)

因为__add__ 产生一个新的浮点数组而不是整数没有问题

于 2013-06-21T06:32:11.433 回答