在Python中随机舍入到整数

Joh*_*nes 6 python integer probability rounding

我正在寻找一种方法,根据从小数点后面的数字得出的概率,将浮点数向上或向下舍入到下一个整数.例如,浮点数6.1可以舍入为6和7.舍入为7的概率为0.1,舍入为6的概率为1-0.1.因此,如果我无限次运行此舍入实验,则所有整数结果的平均值应再次为6.1.我不知道这样的程序是否有名称,以及Python中是否已经实现了函数.当然,如果有可能以相同的方式舍入到例如2位小数,那将是非常好的.

那有意义吗?有任何想法吗?

Chr*_*cke 7

这是一个很好的单衬。通过使用 floor 函数,只有在 0 和 1 之间的随机数足以将其向上舍入到下一个最高整数时,才会向上舍入。这种方法同样适用于正数和负数。

def probabilistic_round(x):
    return int(math.floor(x + random.random()))
Run Code Online (Sandbox Code Playgroud)

考虑负输入的情况x = -2.25。75% 的时间随机数将大于或等于 0.25,在这种情况下,floor 函数将导致 -2 作为答案。其余 25% 的时间该数字将四舍五入为 -3。

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

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


shx*_*hx2 6

你正在寻找的概率是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
Run Code Online (Sandbox Code Playgroud)

编辑:添加一个可选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]
Run Code Online (Sandbox Code Playgroud)


Ker*_*ley 5

对非负 x 执行此操作的最简洁方法是:

int(x + random.random())
Run Code Online (Sandbox Code Playgroud)

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

请注意,如果x == 6,则此表达式保证返回6,因为random.random()始终在 [0, 1) 范围内。

更新:此方法仅适用于非负输入。有关适用于负数的解决方案,请参阅 Chris Locke 的回答。