Search code examples
pythonpandasfloorceil

Using Floor/Ceil to round decimals to integer of 5


I have been using the code below to handily round to 1dp where I needed the .5s to round upwards, e.g. I wanted a value such as 36.25 to round to 36.3, not 36.2.

def my_round(n, ndigits=1):
    try:
       part = n * 10 ** ndigits
       delta = part - int(part)
       # always round "away from 0"
       if delta >= 0.5 or -0.5 < delta <= 0:
           part = math.ceil(part)
       else:
           part = math.floor(part)
       val =  part/(10 ** ndigits)
    except ValueError:
       val = np.nan
    return val

I now need to round a different decimal column in a df to the nearest 5 whole numbers. Can anyone help suggest how I can tweak my original code above to do this? I need, for example, a value such as 702.5000 rounding to 705. Using the normal Round() it obviously goes to 700. In the example, all other normal rounding rules should apply e.g.

702.222 to 700,
707.466 to 705,
703.021 to 705


Solution

  • To round to a certain number of decimal places, use this:

    def my_round(x: float, round_to: float = 5, dp: int = 0) -> float: 
        round_to *= 10**dp 
        x *= 10**dp 
        return ((x + round_to / 2) // round_to * round_to) / 10**dp 
    

    Testing it:

    values = [702.500, 702.222, 707.466, 703.021]
    targets = [705., 700., 705., 705.]
    assert [my_round(x, 5, 0) for x in values] == targets
    assert my_round(3.25, 0.1, 1) == 36.3