【问题标题】:Numpy, why does `x += y` produce a different result than `x = x + y`? [duplicate]Numpy,为什么 `x += y` 产生的结果与 `x = x + y` 不同? [复制]
【发布时间】:2013-06-21 06:24:30
【问题描述】:

在这种情况下,为什么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]

【问题讨论】:

  • 确实是重复的。简短的回答:取决于魔术“dunder”方法__add____iadd__的实现
  • 这不是重复的,这是特定于numpy
  • @jamylak 哦 - 确实,很好,谢谢!

标签: python python-2.7 numpy


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案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__,生成一个新的浮点数组而不是整数没有问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-13
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多