简体   繁体   中英

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

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

Using the decimal module, you could do

import decimal
df = pd.DataFrame(data=[0.5, 1.499999, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5], columns=["orig"])

df.orig = df.orig.apply(
  lambda x: decimal.Decimal(x).to_integral_value(rounding=decimal.ROUND_HALF_UP)
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM