In this case, why does x += y
produce a different result than 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]
Although the linked question explains the general issue, there is a numpy-specific explanation for this particular case. Basically, those answers say "it depends on the type of the variables involved", and what I'm giving below is the explanation for numpy types.
When you do x + y
, numpy uses a "lowest common denominator" datatype for the result. Since x
is int and y
is float, this means it returns a float array.
But when you do x += y
, you are forcing it to conform to the dtype of x
, which is int
. This truncates the decimal portion and leaves all x
values back at 1. This is the way numpy defines the augmented assignment operators: it forces the return value to be of the same dtype as the assignment target.
You can get the first behavior from the second example by doing x = (x + y).astype(int)
(explicitly forcing the dtype back to int). You can get the second behavior from the first example by letting x = np.repeat([1.0], 10)
(using a float makes x
have dtype float, so now you can add y
to it without truncation).
This is due to the difference between __add__
and __iadd__
methods
However usually the difference is seen between mutable vs immutable objects
>>> 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])
contrast with
>>> 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])
so __iadd__
is causing the addition to be truncated back to int when x is int type
This makes sense if you think about it - x can't magically change the type of it's elements (where would it store those extra bytes)
for __add__
there is no problem producting a new array of floats instead of ints
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With