如何避免影响舍入的浮动(in)精度

How can I avoid float (in)accuracy affecting rounding

我在 NHS 工作,负责生成临床结果数据,并且在 Python 3 中存在舍入的长期问题。之前在这里我得到了一个很好的代码来生成我需要的舍入(即不是银行家的四舍五入)但我后来意识到我遇到的另一个问题是浮点字段本身的准确性。我遇到的具体例子如下:

import pandas as pd
import math
raw_data = {'AreaCode' : ['101', '101', '101'],
            'Disaggregation' : ['1864', '65Over', 'Total'],
            'Numerator' : [19.0, 82.0, 101.0],
            'Denominator' : [24.0, 160.0, 184.0]}

Data = pd.DataFrame(raw_data, columns = ['AreaCode', 'Disaggregation', 'Numerator', 'Denominator'])

Data['Outcome'] = (Data['Numerator'] / (Data['Denominator'])*100)

Data

如图所示,65 岁以上人群的结果为 52.250000。这一直四舍五入到 52.2,尽管我使用 ROUND_UP 指示反对这个。

当我将这个 52.2500 结果乘以 1000000000 时,它显示为 512499999,因此四舍五入为 52.2。

如何防范?

我在上面编写了一段代码来演示,但在我的实际练习中,我从 CSV 中导入带有分子和分母的完整原始数据,然后在 Python 中计算结果。我是否需要在开始时向我的 pd.read_csv 添加一些代码以确保 num/denom 不作为浮点数导入?或者确保我的结果计算不是浮点数?或者两者兼而有之?

任何帮助或指点都将非常感谢

詹姆斯

另一个答案:根据@juanpa.arrivallaga的评论你也可以这样解决你的问题:


import pandas as pd
import math
raw_data = {'AreaCode' : ['101', '101', '101'],
            'Disaggregation' : ['1864', '65Over', 'Total'],
            'Numerator' : [19.0, 82.0, 101.0],
            'Denominator' : [24.0, 160.0, 184.0]}

Data = pd.DataFrame(raw_data, columns = ['AreaCode', 'Disaggregation', 'Numerator', 'Denominator'])

Data['Outcome'] = (Data['Numerator'] / (Data['Denominator'])*100)

from decimal import *
def division_using_decimals(numerator,denominator):
    return Decimal(numerator)/Decimal(denominator)

#loop using list comprehension
Data['Outcome_alternative'] = [100*division_using_decimals(Data['Numerator'][x],Data['Denominator'][x]) for x in range(len(Data))]


请注意,如果您将小数 class 传递给浮点数,例如第一个数字 float(Data['Outcome_alternative'][0]) 你会得到四舍五入的数字。如果你使用 str(Data['Outcome_alternative'][0]) 你实际上得到你的号码但是作为一个字符串。