user9413641
user9413641

Reputation:

Weird behaviour of numpy.subtract

Maybe I'm just an idiot, but numpy is doing something I have no idea how to explain, please help me understand how this is happening:

The code below produces the output I am expecting:

import numpy as np


exponents = np.indices((4, 4))[:, ::2].reshape((2, -1)).T

print(exponents)
# print(np.subtract(exponents, [0, 1]))
print(np.subtract(exponents, [0, 1], where=exponents > 0))
print(exponents)

output is:

[[0 0]
 [0 1]
 [0 2]
 [0 3]
 [2 0]
 [2 1]
 [2 2]
 [2 3]]
[[0 0]
 [0 0]
 [0 1]
 [0 2]
 [2 0]
 [2 0]
 [2 1]
 [2 2]]
[[0 0]
 [0 1]
 [0 2]
 [0 3]
 [2 0]
 [2 1]
 [2 2]
 [2 3]]

but if I un-comment the line where I subtract without the "where" argument, ie:

import numpy as np


exponents = np.indices((4, 4))[:, ::2].reshape((2, -1)).T

print(exponents)
print(np.subtract(exponents, [0, 1]))
print(np.subtract(exponents, [0, 1], where=exponents > 0))
print(exponents)

then I get the following output, which I can't explain:

[[0 0]
 [0 1]
 [0 2]
 [0 3]
 [2 0]
 [2 1]
 [2 2]
 [2 3]]
[[ 0 -1]
 [ 0  0]
 [ 0  1]
 [ 0  2]
 [ 2 -1]
 [ 2  0]
 [ 2  1]
 [ 2  2]]
[[ 0 -1]
 [ 0  0]
 [ 0  1]
 [ 0  2]
 [ 2 -1]
 [ 2  0]
 [ 2  1]
 [ 2  2]]
[[0 0]
 [0 1]
 [0 2]
 [0 3]
 [2 0]
 [2 1]
 [2 2]
 [2 3]]

Ie. now the output of np.subtract(exponents, [0, 1], where=exponents > 0) has changed..

The reason I added the line print(exponents) to the end was because I suspected that the np.subtract(..) function was subtracting in-place, but as is evident this is not what is going on..

please help me understand what is going wrong here

btw. my numpy version is 1.21.1

Upvotes: 0

Views: 113

Answers (1)

hpaulj
hpaulj

Reputation: 231335

Your calculation with my suggested out correction:

In [36]: exponents = np.indices((4, 4))[:, ::2].reshape((2, -1)).T
    ...: 
In [37]: exponents
Out[37]: 
array([[0, 0],
       [0, 1],
       [0, 2],
       [0, 3],
       [2, 0],
       [2, 1],
       [2, 2],
       [2, 3]])
In [38]: exponents-[0,1]
Out[38]: 
array([[ 0, -1],
       [ 0,  0],
       [ 0,  1],
       [ 0,  2],
       [ 2, -1],
       [ 2,  0],
       [ 2,  1],
       [ 2,  2]])
In [39]: mask = exponents>0
In [40]: mask
Out[40]: 
array([[False, False],
       [False,  True],
       [False,  True],
       [False,  True],
       [ True, False],
       [ True,  True],
       [ True,  True],
       [ True,  True]])
In [41]: np.subtract(exponents,[0,1],where=mask)
Out[41]: 
array([[           0, 450971566194],
       [           0,            0],
       [489626271861,            1],
       [433791696995,            2],
       [           2, 416611827830],
       [           2,            0],
       [           2,            1],
       [           2,            2]])

Note the 'unexpected' values where mask is false. Use out to predefine those values

In [42]: np.subtract(exponents,[0,1],where=mask, out=exponents.copy())
Out[42]: 
array([[0, 0],
       [0, 0],
       [0, 1],
       [0, 2],
       [2, 0],
       [2, 0],
       [2, 1],
       [2, 2]])

Upvotes: 0

Related Questions