2013-09-27 17 views
2

我正在寻找一种方法,根据从小数点后的数字导出的概率向上或向下舍入到下一个整数的浮点数。例如,浮点数6.1可以舍入到6和7.四舍五入到7的概率是0.1,四舍五入到6的概率是1-0.1。所以如果我无限次地运行这个舍入实验,所有整数结果的平均值应该是6.1。我不知道是否有这样一个过程的名称,以及是否已经在Python中实现了函数。 当然,如果有可能也轮到例如2位小数位的方式相同。在Python中对整数进行随机舍入

这有道理吗?有任何想法吗?

+0

我看不出任何意义在这个努力( - : - 但这是可能的;让你的有效数字s作为一个整数,并乘以'numpy.random.rand()'为你的舍入决定,我猜。 – Faultier

回答

4

您正在寻找的概率是x-int(x)

要使用此概率样本,做random.random() < x-int(x)

import random 
import math 
import numpy as np 

def prob_round(x): 
    sign = np.sign(x) 
    x = abs(x) 
    is_up = random.random() < x-int(x) 
    round_func = math.ceil if is_up else math.floor 
    return sign * round_func(x) 

x = 6.1 
sum(prob_round(x) for i in range(100))/100. 
=> 6.12 

编辑:添加一个可选的prec参数:

def prob_round(x, prec = 0): 
    fixup = np.sign(x) * 10**prec 
    x *= fixup 
    is_up = random.random() < x-int(x) 
    round_func = math.ceil if is_up else math.floor 
    return round_func(x)/fixup 

x = 8.33333333 
[ prob_round(x, prec = 2) for i in range(10) ] 
=> [8.3399999999999999, 
8.3300000000000001, 
8.3399999999999999, 
8.3300000000000001, 
8.3300000000000001, 
8.3300000000000001, 
8.3300000000000001, 
8.3300000000000001, 
8.3399999999999999, 
8.3399999999999999] 
+0

@SteveJessop很好。我修复了我的代码。 – shx2

+0

这可以实现没有分支? –

+0

@étale-cohomology,当然。你可以这样做:'math.floor(x)+(random.random() shx2

0

我也有一个解决方案基础上的随机和二项式功能上来代码已由shx2提供:

def prob_round(x, prec = 0): 
    fixup = np.sign(x) * 10**prec 
    x *= fixup 
    round_func = int(x) + np.random.binomial(1,x-int(x)) 
    return round_func/fixup 
2

For舍入正值为整数,你可以这样做很简洁:

x = int(x) + (random.random() < x - int(x)) 

这工作,因为Python的bool类型的int一个子类。值True等于1 False等于0

0

最简洁的方式做到这一点是:

int(x + random.random()) 

例如如果x == 6.1,则有10%的机会,random.random()将是大足以使x + random.random() >= 7

请注意,如果x == 6,那么这个表达式保证返回6,因为random.random()总是在[0,1]范围内。

1

这是一个很好的单行本。通过使用发言权函数,只有当0和1之间的随机数足以使其达到下一个最高整数时,它才会被四舍五入。这种方法也适用于正数和负数。

def probabilistic_round(x): 
    return int(math.floor(x + random.random())) 

考虑负输入的情况x = -2.25。 75%的随机数将大于或等于0.25,在这种情况下,底线函数将导致-2作为答案。另外25%的时间数字将舍入到-3。

四舍五入到不同的小数位可以作如下修改:

def probabilistic_round(x, decimal_places=0): 
    factor = 10.0**decimal_places 
    return int(math.floor(x*factor + random.random()))/factor 
0

这里有一个简单的方法:

x = round(random.random()*100) 

*100位意味着1到100
如果*200,它意思是1至200.