Search code examples
pythonpandasrounding

Python3 pandas dataframe round .5 always up


According to the documentation, Python rounds values toward the even choice if the upper and lower rounded values are equally close to the original number.

I want to round values in my pandas.DataFrame such that 0.5 is always rounded up.

A way to fix it would be to use the decimal module with Decimal datatype as described here: How to properly round up half float numbers in Python?

import pandas as pd

if __name__ == "__main__":
    df = pd.DataFrame(data=[0.5, 1.499999, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5], columns=["orig"])
    df["round"] = df.round()
    print(df)

which outputs:

       orig  round
0  0.500000    0.0
1  1.499999    1.0
2  1.500000    2.0
3  2.500000    2.0
4  3.500000    4.0
5  4.500000    4.0
6  5.500000    6.0
7  6.500000    6.0

I tried to do something like:

df["round"] = df["orig"].values.astype(Decimal).round()

but this does not work. Is there a simple and readable solution to ensure that .5 is always rounded up?

EDIT

I'm not sure if the links in the comments answer the question. The solution presented in the links is casting every float to a string and are manipulating the strings which seems ridiculous for large DataFrames. (and is very hard to read/understand). I was hoping there is a simple function to use like in the decimal package


Solution

  • You can add some tiny value to orig when the decimal is 0.5. That guarantees that any integer + 0.5 will always round up to the next integer.

    import numpy as np
    df['round_up'] = np.round(np.where(df['orig'] % 1 == 0.5,
                                       df['orig'] + 0.1,
                                       df['orig']))
    print(df)
           orig  round_up
    0  0.500000       1.0
    1  1.499999       2.0
    2  1.500000       2.0
    3  2.500000       3.0
    4  3.500000       4.0
    5  4.500000       5.0
    6  5.500000       6.0
    7  6.500000       7.0