Qian
Qian

Reputation: 73

numpy: unexpected result when dividing a vertical array by one of its own elements

So, I created an vertical numpy array, used the /= operator and the output seems to be incorrect. Basically if x is a vector, s a scalar. I would expect x /= s have every entry of x divided by s. However, I couldn't make much sense of the output. The operator is only applied on part of the entries in x, and I am not sure how they are chosen.

In [8]: np.__version__
Out[8]: '1.10.4'

In [9]: x = np.random.rand(5,1)

In [10]: x
Out[10]:
array([[ 0.47577008],
       [ 0.66127875],
       [ 0.49337183],
       [ 0.47195985],
       [ 0.82384023]])   ####

In [11]: x /= x[2]

In [12]: x
Out[12]:
array([[ 0.96432356],
       [ 1.3403253 ],
       [ 1.        ],
       [ 0.95660073],
       [ 0.82384023]])   #### this entry is not changed.

Upvotes: 7

Views: 121

Answers (2)

Tom
Tom

Reputation: 343

Your value of x[2] changes to 1 midway through the evaluation. you need to make a copy of the value then divide each element by it, either assign it to another variable or use copy i.e.

from copy import copy
x /= copy(x[2])

To understand why we need to do this lets look under the hood of what is happening.

In [9]: x = np.random.rand(5,1)

Here we define x as an array, but what isn't exactly clear that each element in this array is technically an array also. This is the important distinction, as we are not dealing with defined values rather numpy array objects so in the next line:

In [11]: x /= x[2]

We end up essentially 'looking up' the value in x[2] which returns an array with one value, but because we're looking this up each time it is possible to change.

A cleaner solution would be to flatten the array into 1d therefore x[2] with now equal 0.49337183 instead of array( [0.49337183])

So before we do x /= x[2] we can call x = x.flatten()

Or better yet keep it 1d from the start x = np.random.rand(5)

And as for the reason x[3] changes and x[4] does not, the only real helpful answer I can give is that the division does not happen in order, complex buffering timey wimey stuff.

Upvotes: 6

AlexDC
AlexDC

Reputation: 21

It is only for odd size of vector in theory but if you do : x = np.random.rand(5,1) a = x[2]*1 x/=a it will be working

Upvotes: 0

Related Questions