IT干货网

Python 百分比舍入

think 2025年05月04日 编程设计 319 0

这个问题在这里已经有了答案:





How to make rounded percentages add up to 100%

(22 个回答)


7年前关闭。




我知道如何在 Python 中对数字进行四舍五入,这不是一个简单的技术问题。

我的问题是,四舍五入会使一组百分比加起来不等于 100%,但从技术上讲,它们应该是这样。

例如:

a = 1 
b = 14 

我想计算 (a + b) 中 a 和 (a + b) 中 b 的百分比。

答案应该是
a/(a + b) = 1/15  
b/(a + b) = 14/15 

当我尝试对这些数字进行四舍五入时,我得到了
1/15 = 6.66  
14/15 = 93.33  

(我在做地板),这使得这两个数字加起来不是 100%。

在这种情况下,我们应该为 1/15 做上限,即 6.67,为 14/15 做下限,即 93.33。现在它们加起来是 100%。这种情况下的规则应该是“四舍五入到最接近的数字”

但是,如果我们有更复杂的情况,比如 3 个数字:
a = 1 
b = 7 
c = 7 

地板:
1/15 = 6.66 
7/15 = 46.66 
7/15 = 46.66 

加起来不等于 100%。

天花板:
1/15 = 6.67 
7/15 = 46.67 
7/15 = 46.67 

加起来不等于 100%。

四舍五入(到最接近的数字)与上限相同。仍然没有达到 100%。

所以我的问题是我应该怎么做才能确保它们在任何情况下都达到 100%。

提前致谢。

更新:
感谢评论中的提示。我从重复的帖子答案中获取了“最大余数”解决方案。

代码是:
def round_to_100_percent(number_set, digit_after_decimal=2): 
    """ 
        This function take a list of number and return a list of percentage, which represents the portion of each number in sum of all numbers 
        Moreover, those percentages are adding up to 100%!!! 
        Notice: the algorithm we are using here is 'Largest Remainder' 
        The down-side is that the results won't be accurate, but they are never accurate anyway:) 
    """ 
    unround_numbers = [x / float(sum(number_set)) * 100 * 10 ** digit_after_decimal for x in number_set] 
    decimal_part_with_index = sorted([(index, unround_numbers[index] % 1) for index in range(len(unround_numbers))], key=lambda y: y[1], reverse=True) 
    remainder = 100 * 10 ** digit_after_decimal - sum([int(x) for x in unround_numbers]) 
    index = 0 
    while remainder > 0: 
        unround_numbers[decimal_part_with_index[index][0]] += 1 
        remainder -= 1 
        index = (index + 1) % len(number_set) 
    return [int(x) / float(10 ** digit_after_decimal) for x in unround_numbers] 

经测试,似乎工作正常。

请您参考如下方法:

正如其他人所评论的那样,如果您的数字像您的示例一样漂亮且圆润,您可以使用 fractions模块来保持有理数的准确性:

In [2]: from fractions import Fraction 
 
In [5]: a = Fraction(1) 
 
In [6]: b = Fraction(14) 
 
In [7]: a/(a+b) 
Out[7]: Fraction(1, 15) 
 
In [8]: a/(a+b) + (b/(a+b)) 
Out[8]: Fraction(1, 1) 

如果你有非常奇数的分数,这显然看起来不太好。


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!