How to round away from zero

Question:

I am new to python, and as far as I found out, python doesn’t have sort of “mathematical” rounding. Or does it have?
I have a temperature array, for example:

temp = [-20.5, -21.5, -22.5, -23.5, 10.5, 11.5, 12.5, 13.5]

I couldn’t fine the way to round values mathematically to:

>> [-21, -21, -22, -22, -22, -24, -23, -23, -23, -23, -24, ...]

So that -20.5 rounded to -21, -21.5 rounded to -22, -23.5 rounded to -24, 10.5 rounded to 11, 11.5 rounded to 12, 12.5 rounded to 13. Mathematical accuracy is important in my case.

The best option for me is using function like numpy.around() due to it does rounding for all the values at ones, not one by one (I suppose, it is faster). Is there such a function, or such a way at all?

Results i got:

np.around(temp, decimals=0)
>>[-20. -22. -22. -24.  10.  12.  12.  14.]
np.rint(temp)
>>[-20. -22. -22. -24.  10.  12.  12.  14.]
np.round(temp)
>>[-20. -22. -22. -24.  10.  12.  12.  14.]
np.trunc(temp)
>>[-20. -21. -22. -23.  10.  11.  12.  13.]
Asked By: Outlaw

||

Answers:

as chepner said, the type of rounding you describing is round away from zero.

you could do the following:

import math
import numpy as np

def round_away_from_zero(x):
    a = abs(x)
    r = math.floor(a) + math.floor(2 * (a % 1))
    return r if x >= 0 else -r

temp = [-20.5, -21.5, -22.5, -23.5, 10.5, 11.5, 12.5, 13.5]
temp_np = np.array(temp)
t = map(round_away_from_zero, temp_np)
print(t)

the output you get is:

[-21.0, -22.0, -23.0, -24.0, 11.0, 12.0, 13.0, 14.0]

Note

follwoing the user comment Ill briefly explain about np.array() and map():

  1. np.array(): this function takes an array object and transform it to a Numpy object allowing to use functionality that associated with it, you can read about it in the following link
  2. map(): function is used to apply a function on all the elements of specified iterable and return map object. Python map object is an iterator, so we can iterate over its elements. We can also convert map object to sequence objects such as list, tuple etc.
Answered By: David

numpy has a around, which documents:

Notes
-----
For values exactly halfway between rounded decimal values, NumPy
rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0,
-0.5 and 0.5 round to 0.0, etc. Results may also be surprising due
to the inexact representation of decimal fractions in the IEEE
floating point standard [1]_ and errors introduced when scaling
by powers of ten.

Rounding to nearest even is just as valid, mathematically, as rounding away from zero. The purpose of such rules is to provide consistency, and some degree of statistical uniformity (reduce bias).

But it also warns that float values are seldom ‘exactly’ half’s. We frequently get questions about values that display like 20.49999999.

===

A numpy version of the round_away_from_zero function in the other answer:

def round_away(x):
    a = np.abs(x)
    b = np.floor(a) + np.floor(2*(a%1))
    return np.sign(x)*b

In [279]: np.array(temp)                                                        
Out[279]: array([-20.5, -21.5, -22.5, -23.5,  10.5,  11.5,  12.5,  13.5])
In [280]: round_away(temp)                                                      
Out[280]: array([-21., -22., -23., -24.,  11.,  12.,  13.,  14.])
Answered By: hpaulj

Late but here’s a clever(?) way:

arr = np.array([1.2, -1.2])
arr_rounded = np.copysign(np.ceil(np.abs(arr)), arr)

Output being: [2, -2]

Answered By: darlove
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.