7

I have this array:

arr = np.array([66.5, 89.4000015, 57.2000008, 86.9000015, 64.5999985,
      92.3000031, 74.1999969, 76.0999985, 92.0999985, 81.6999969,
      72.0999985, 78.8000031, 81.4000015, 95.4000015, 73.5      ,
      58.5999985, 68.3000031, 68.9000015, 68.6999969, 92.       ])

I tried to round each number, and used np.around:

[in]  np.around(arr, 2)

[out] array([66.5, 89.4, 57.2, 86.9, 64.6, 92.3, 74.2, 76.1, 92.1, 81.7, 72.1,
   78.8, 81.4, 95.4, 73.5, 58.6, 68.3, 68.9, 68.7, 92. ])

[in]  np.around(arr, 4)

[out] array([66.5, 89.4, 57.2, 86.9, 64.6, 92.3, 74.2, 76.1, 92.1, 81.7, 72.1,
   78.8, 81.4, 95.4, 73.5, 58.6, 68.3, 68.9, 68.7, 92. ])

[in] np.around(arr, 5)
[out] array([66.5, 89.4, 57.2, 86.9, 64.6, 92.3, 74.2, 76.1, 92.1, 81.7, 72.1,
   78.8, 81.4, 95.4, 73.5, 58.6, 68.3, 68.9, 68.7, 92. ])

[in]  np.around(arr, 6)

[out] array([66.5     , 89.400002, 57.200001, 86.900002, 64.599998, 92.300003,
   74.199997, 76.099998, 92.099998, 81.699997, 72.099998, 78.800003,
   81.400002, 95.400002, 73.5     , 58.599998, 68.300003, 68.900002,
   68.699997, 92.      ])

When the number of decimals is less than 5, the np.around() does not work. When it is larger than 6, the np.around is working well.

Any help is appreciated.

Anne

girish946
  • 745
  • 9
  • 24
anne
  • 71
  • 1
  • 1
  • 3
  • What do you mean by it doesn't work? It seems to work quite well. – ayhan Jul 15 '18 at 15:26
  • Can you say what results you expect? Those results look fine to me. – Mark Dickinson Jul 15 '18 at 15:26
  • I believe you might be confusing [`numpy.ceil`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ceil.html) with [`numpy.around`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.around.html). – Luca Cappelletti Jul 15 '18 at 15:30
  • Or that NumPy rounds to the nearest even value. – Zev Jul 15 '18 at 15:30
  • I am expecting that array[66.5000, 89.4000, 57.2000, ....] when I used np.around(arr, 4). But it gave me array[66.5, 89.4, 57.2, ....] – anne Jul 15 '18 at 15:31
  • @anne what "that"? – Luca Cappelletti Jul 15 '18 at 15:31
  • As @MarkDickinson said, you need to provide your expected results and point out how they differ. – Zev Jul 15 '18 at 15:32
  • @anne `66.5000` and `66.5` are the same number. Their string representation is different. You can use float formatting to achieve that result. But do you only want to display them or are you trying to write to a file? (See https://stackoverflow.com/questions/21008858/formatting-floats-in-a-numpy-array for a couple of options). – ayhan Jul 15 '18 at 15:38
  • I am expecting that the results from np.around(arr,4) should be different from that of np.around(arr,2). That is to say, the result of np.around(arr,2) should be array[66.50, 89.40, 57.20, ....], while that of np.around(arr,4) should be array[66.5000, 89.4000, 57.2000,.... ] Thanks a lot. – anne Jul 15 '18 at 15:38
  • That is not rounding, adding zeros to floats does nothing unless you are treating these numbers as strings. For that you have the [`.nf` notation](https://stackoverflow.com/questions/1995615/how-can-i-format-a-decimal-to-always-show-2-decimal-places), where `n` is the number of figures you want to show. – Luca Cappelletti Jul 15 '18 at 15:41
  • @user2285236, Luca Thanks a lot for the explanation. I understood now. Maybe I need to format them to achieve what I want. Thank all. – anne Jul 15 '18 at 15:43

1 Answers1

4

How to: round

Based on the "unexpected behaviour" you are describing, I believe you haven't clear which round operations or the effect they have on numbers or how to format floats as strings.

Let's explore the differences when rounding to n=4 digits different values.

Baseline

We define an array with 13 values (13 just to get some digits), from 0 to 1.

values = np.linspace(0, 1, 13)

The array contains:

array([0.        , 0.08333333, 0.16666667, 0.25      , 0.33333333,
       0.41666667, 0.5       , 0.58333333, 0.66666667, 0.75      ,
       0.83333333, 0.91666667, 1.        ])

numpy.around

numpy.around will increase the value of the n-th figure when the n+1-th is greater or equal to 5, do nothing otherwise. It is the same as numpy.round.

np.round(values, n)
>>> array([0.    , 0.0833, 0.1667, 0.25  , 0.3333, 0.4167, 0.5   , 0.5833,
   0.6667, 0.75  , 0.8333, 0.9167, 1.    ])

numpy.ceil

numpy.ceil will increase the value of the integer part when there exists digits and drop the digits.

np.ceil(r)
>>> array([0., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

numpy.floor

numpy.floor will just drop the digits.

np.floor(r)
>>> array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.])

Number string formatting

There are a multitude of ways to format numbers as strings: we will explore some of the more commonly used.

Formatting as floats

To format floats you use the symbol .nf, where n is the number of digits you want to leave. It will drop all the following figures and add zeros as padding when required to do so.

[ "{:0.4f}".format(v) for v in r]
>>> ['0.0000', '0.0833', '0.1667', '0.2500', '0.3333', '0.4167', '0.5000',
     '0.5833', '0.6667', '0.7500', '0.8333', '0.9167', '1.0000']

Formatting as percentages

To format floats as percentages you use the symbol .n%, where n is the number of digits you want to leave, considering that the number will be multiplied by 100. It will drop all the following figures and add zeros as padding when required to do so.

[ "{:0.4%}".format(v) for v in r]
>>> ['0.0000%', '8.3333%', '16.6667%', '25.0000%', '33.3333%', '41.6667%',
'50.0000%', '58.3333%', '66.6667%', '75.0000%', '83.3333%', '91.6667%',
'100.0000%']

Formatting in scientific notation

To format floats as percentages you use the symbol .ne, where n is the number of digits you want to leave, considering that the number will be converted to scientific notation. It will drop all the following figures and add zeros as padding when required to do so, adding at the end the exponent of the number in scientific notation.

[ "{:e}".format(v) for v in r]
>>> [
    '0.0000e+00', '8.3333e-02', '1.6667e-01', '2.5000e-01', '3.3333e-01',
    '4.1667e-01', '5.0000e-01', '5.8333e-01', '6.6667e-01', '7.5000e-01',
    '8.3333e-01', '9.1667e-01', '1.0000e+00'
]

Bonus: formatting complex numbers

Suppose you have a complex number a = 3j+2: to print its components you would proceed by accessing its attributes:

"The real component is {0.real} and the imaginary one is {0.imag}".format(a)
>>> 'The real component is 2.0 and the imaginary one is 3.0'
Luca Cappelletti
  • 2,485
  • 20
  • 35