Python:四舍五入误差对均匀分布造成扭曲

4
我需要抽取10个0到1之间均匀分布的随机数。因此,我认为以下Python代码可以实现这一目标:
positions = []
for dummy_i in range(1000000):
    positions.append(round(random.random(),1))

然而,将结果放入直方图中,结果如下所示:

Frequency of numbers rounded to 1 decimal place

因此,四舍五入似乎破坏了由random.random()生成的均匀分布。我想知道是什么原因导致了这种情况,以及如何防止这种情况发生。谢谢您的帮助!

1
一个简单的获取计数的方法(并且可以看到是直方图分箱导致了扭曲),就是使用 collections.Counter:尝试运行 collections.Counter(round(random.random(), 1) for _ in range(10**6)),你会发现对于 0.10.9 的计数大致相等。 - Mark Dickinson
4个回答

3

看起来你的代码后面有问题...(例如在收集统计信息时)。检查这个较小的片段:

import random, collections
data = collections.defaultdict(int)
for x in range(1000000):
    data[round(random.random(),1)] += 1
print(data)

你会发现,01的样本数量大约只有其他值的一半,而其他值则几乎是均匀分布的。
例如,我得到了:
defaultdict(<class 'int'>,
            {0.4: 100083,
             0.9: 99857,
             0.3: 99892,
             0.8: 99586,
             0.5: 100108,
             1.0: 49874,     # Correctly about half the others
             0.7: 100236,
             0.2: 99847,
             0.1: 100251,
             0.6: 100058,
             0.0: 50208})    # Correctly about half the others

2
您创建直方图的方式是错误的。您应该得到大约:
0和1的50k
所有其他数字的100k
但是您的第三个箱子从包括0.2到包括0.3,结果为200k,而您的第四个箱子从0.3独占到0.4独占,结果为零。
尝试创建一个边缘为0.05、0.15等的直方图,这样就不会有如此精度误差了。

0

试一下这个

positions = []
for dummy_i in range(10):
    positions.append(random.randint (0, 10) / 10)

0

我认为在这里使用Numpy可能会更加简洁高效:

import numpy as np
positions = np.random.random(10000)
positions = np.round(positions, decimals=3)

嗯,这并不是对OP问题的答案:它只是一个伪装成答案的评论。 - Mark Dickinson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接