python numpy arange unexpected results
Perhaps it has to do with limitations on floating point numbers. Due to machine precision, it is not possible to store every conceivable value perfectly as a floating point. For example:
>>> 8.4
8.4000000000000004
>>> 8.35
8.3499999999999996
So, 8.4 as a floating point is slightly greater than the actual value of 8.4, while 8.35 as a floating point is a tiny bit less.
Python numpy unexpected results in arange and linspace
In the Python console you will see
>>> 0.29/0.01
28.999999999999996
>>> import numpy as np
>>> np.int32(0.29/0.01)
28
So you are on the right path. This is due to floating point calculation. As soon as you cast it to np.int32
, the decimal places will be truncated and the result is 28
. Instead of just casting, you should round the result:
>>> np.int32(np.round(0.29/0.01))
29
For your application that means you have to write
lattice = np.asarray(np.round(lattice/cell_size),dtype=np.int32) ###This is supposed to contain matrix indices.
python numpy arange: strange behavior
Because of floating point error, 1.1
, 0.01
and 0.12
are not as precise as one might expect, nor are mathematical operations between them. For example:
>>> 1.1 + 0.01 + 0.01 + 0.01
1.1300000000000001
See also:
>>> decimal.Decimal(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
>>> decimal.Decimal(1.12)
Decimal('1.12000000000000010658141036401502788066864013671875')
If they were precise, np.arange(1.1, 1.12, 0.01)
would be array([1.1 , 1.11])
np.arange
specification mentions that as well: For the stop
argument it writes:
stop : number
End of interval. The interval does not include this value, except in
some cases where step is not an integer and floating point round-off
affects the length of out.
You can avoid the problem by always specifying an upper limit which is between two steps, rather than exactly on the boundary:
>>> np.arange(1.1, 1.115, 0.01)
array([1.1 , 1.11])
>>> np.arange(1.1, 1.125, 0.01)
array([1.1 , 1.11, 1.12])
>>> np.arange(1.1, 1.135, 0.01)
array([1.1 , 1.11, 1.12, 1.13])
Unexpected output for numpy.arange with step size of 0.005
linspace
might be better suited to your needs
In [401]: np.linspace(2.23, 2.24,3)
Out[401]: array([ 2.23 , 2.235, 2.24 ])
You specify the number of steps, rather than the interval. It has additional parameters to control details like the inclusion, or not, of the end point.
In [415]: np.linspace(2.23, 2.24,2,endpoint=False)
Out[415]: array([ 2.23 , 2.235])
python numpy arange unexpected results
Perhaps it has to do with limitations on floating point numbers. Due to machine precision, it is not possible to store every conceivable value perfectly as a floating point. For example:
>>> 8.4
8.4000000000000004
>>> 8.35
8.3499999999999996
So, 8.4 as a floating point is slightly greater than the actual value of 8.4, while 8.35 as a floating point is a tiny bit less.
Is Numpy giving unexpected results?
Take np.random.choice(np.arange(0,X.shape[0]), size = train_size, replace = False)
The problem is, that np.random.randint
will not be injectiv, basically the number 1 might apear twice. This means that index 1 will be set to True
twice, while another one will not be set to True
.
The np.random.choice
function ensures, that every number will occur at most once (if you set replace = False
numpy.arange makes no sense at all. How does it work?
It's floating point precision, e.g. see this question: python numpy arange unexpected results
You could get around it like so:
>>> np.arange(14.04, 14.839, 0.08)
array([ 14.04, 14.12, 14.2, 14.28, 14.36, 14.44, 14.52, 14.6, 14.68, 14.76])
...but this is pretty hacky. It's usually a better idea to use numpy.linspace()
, but then you have to give the number of steps, not the interval, so it can be a bit of a pain.
>>> np.linspace(14.04, 14.76, 9)
array([ 14.04, 14.13, 14.22, 14.31, 14.4, 14.49, 14.58, 14.67, 14.76])
Choose your poison!
Related Topics
Override Python's 'In' Operator
Python Eval: Is It Still Dangerous If I Disable Builtins and Attribute Access
Intercepting Stdout of a Subprocess While It Is Running
Is' Operator Behaves Differently When Comparing Strings with Spaces
Display Special Characters When Using Print Statement
How to Run Python Script Without Typing 'Python ...'
How to Suppress the Newline After a Print Statement
Is the Single Underscore "_" a Built-In Variable in Python
Link Atlas/Mkl to an Installed Numpy
How to Find Out If Python Is Compiled with Ucs-2 or Ucs-4
How Can Strings Be Concatenated
Pandas: Filtering Multiple Conditions