I have a Numpy array that I obtained by multiplying a Numpy array with a float.
a = np.array([3, 5, 7, 9]) * 0.1
The resulting numbers are precise without any rounding.
>>> a
array([0.3 0.5 0.7 0.9])
However, if I turn my array into a list with a.tolist()
, there are entries like 0.30000000000000004
in my list instead of 0.3
.
>>> a.tolist()
[0.30000000000000004, 0.5, 0.7000000000000001, 0.9]
My question is, how can I avoid this, and if someone knows, out of pure interest, why is this happening. Thank you very much for your help.
CodePudding user response:
This issue comes with floating points in general (do 3 * .1
in your Python console). In your case, you can simply divide by 10 rather than multiple by .1.
a = np.array([3, 5, 7, 9]) / 10
See also: Floating Point Error Mitigation Decimal Module
CodePudding user response:
This is not a problem with Numpy. Instead, this is a well-known problem with floating-point values in Python and in other languages as well.
You can try this in the Python terminal.
>>> 3 * 0.1
0.30000000000000004
However, here is the difference.
The difference here is how Numpy and Python represent these values.
When you print a Numpy array, it passes the array through np.array_repr
and returns a string representation of the array.
Notice the parameter precision
. By default, it is set to numpy.get_printoptions()['precision']
or 8
.
>>> np.get_printoptions()['precision']
8
Which is way before the precision 17
of 0.30000000000000004
. Therefore, the result that we see is rounded to 0.3
.
Let's try out some more with the precision
settings.
>>> a = np.array([3, 5, 7, 9]) * 0.1
precision=17
>>> print(np.array_repr(a, precision=17))
array([0.30000000000000004, 0.5, 0.7000000000000001, 0.9])
precision=16
>>> print(np.array_repr(a, precision=16))
arrayarray([0.3, 0.5, 0.7000000000000001, 0.9])
precision=15
>>> print(np.array_repr(a, precision=15))
array([0.3, 0.5, 0.7, 0.9])
When you convert the Numpy array into a list, because lists do not have the precision feature when it comes to representing the values, the float values in lists are displayed as they are.
If you want the values to look the same when converting into a list, at least round them to the eighth decimal place.
>>> print(list(np.round(a, 8)))
[0.3, 0.5, 0.7, 0.9]