0

here is my code

import numpy
a = numpy.arange(0.5, 1.5, 0.1, dtype=numpy.float64)
print(a)
print(a.tolist())

>>>[0.5 0.6 0.7 0.8 0.9 1.  1.1 1.2 1.3 1.4]
>>>[0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999, 0.9999999999999999, 1.0999999999999999, 1.1999999999999997, 1.2999999999999998, 1.4]

When trying to convert numpy array to list getting this problem with value like 0.7999999999999999 in place of 0.8

please help me to convert numpy array to normal python list without losing the decimal value.

a_guest
  • 34,165
  • 12
  • 64
  • 118
  • 2
    Numpy arrays have a "pretty" representation which hides some of the digits. This can be controlled via [`numpy.set_printoptions`](https://numpy.org/doc/stable/reference/generated/numpy.set_printoptions.html) – a_guest Jan 15 '21 at 07:32
  • the suggestion is not working because when im printing variable "a" im getting te value without losing decimal but when im converting variable "a" to a list then im losing the decimal values – Md Talha Zubayer Jan 15 '21 at 07:36
  • You're not gaining or losing any precision in the conversion. This is purely a difference in display handling. – user2357112 Jan 15 '21 at 07:40
  • if i use numpy.set_printoptions maybe im going to get 0.7 instead of 0.8 – Md Talha Zubayer Jan 15 '21 at 07:40
  • "if i use numpy.set_printoptions maybe im going to get 0.7 instead of 0.8" - no you're not. That's an unfounded fear. – user2357112 Jan 15 '21 at 07:41
  • can you please give me example how to use it when im converting an array i can do that for a single value but how can i do that to a array? – Md Talha Zubayer Jan 15 '21 at 07:43
  • use np.round to set the level of precision on the array data – Golden Lion Feb 11 '21 at 12:55

2 Answers2

1
import numpy

a = numpy.arange(0.5, 1.5, 0.1, dtype=numpy.float64)

print(a)

a = numpy.round(a.astype(numpy.float64), 1)

print (a)

print (a.tolist())

Output:

[0.5 0.6 0.7 0.8 0.9 1.  1.1 1.2 1.3 1.4]
[0.5 0.6 0.7 0.8 0.9 1.  1.1 1.2 1.3 1.4]
[0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4]

You can use numpy.round() with astype() method to round your float, getting something consistant upon tolist() conversion.

Synthase
  • 5,849
  • 2
  • 12
  • 34
1

By the conversion via .tolist() you're not gaining or loosing any precision. You're just converting to another data type which chooses to represent itself differently. You seem to be thinking that by the conversion it turns the 0.8 into 0.7999999999999999, but the situation is, it has never been 0.8. This is due to limited floating point precision. You can verify yourself:

>>> import numpy
>>> a = numpy.arange(0.5, 1.5, 0.1, dtype=numpy.float64)
>>> a
array([0.5, 0.6, 0.7, 0.8, 0.9, 1. , 1.1, 1.2, 1.3, 1.4])
>>> a[3]
0.7999999999999999

The situation is that that every type can decide how its instances are represented via __repr__ or __str__. In this specific case np.ndarray decides to show a rounded version of its elements for more clarity. This can be controlled via numpy.set_printoptions. This function only affects how arrays are displayed:

>>> numpy.set_printoptions(floatmode='unique')
>>> a
array([0.5               , 0.6               , 0.7               ,
       0.7999999999999999, 0.8999999999999999, 0.9999999999999999,
       1.0999999999999999, 1.1999999999999997, 1.2999999999999998,
       1.4               ])

A note on np.arange from the docs:

When using a non-integer step, such as 0.1, the results will often not be consistent. It is better to use numpy.linspace for these cases.

Here are the results for linspace:

>>> np.linspace(0.5, 1.5, 11)
array([0.5               , 0.6               , 0.7               ,
       0.8               , 0.9               , 1.                ,
       1.1               , 1.2000000000000002, 1.3               ,
       1.4               , 1.5               ])
a_guest
  • 34,165
  • 12
  • 64
  • 118