【问题标题】:How do you generate a random number in a range with a specific average in python? [closed]如何在 python 中生成具有特定平均值的范围内的随机数? [关闭]
【发布时间】:2013-12-26 20:38:09
【问题描述】:

假设我想生成一个介于 -1000 和 1000 之间的随机数,并且我希望平均值为 x。我该怎么做?

编辑:为了清楚起见,生成的数字应符合标准正态分布,平均为 x。

因此,如果我生成一千个数字并找到它们的平均值,那就是 x。

我试过了,但它似乎不起作用:

sum_ = 0
for i in range(0, 10):
  sum_ += random.triangular(-1000, 1000, 10)
print sum_ / 10

我希望这能给我一些 ~10 的东西,但我显然没有使用正确的代码。

【问题讨论】:

  • 随机整数还是随机浮点数?
  • 你试过什么?
  • 我是编码新手,我尝试了 random.triangular,但它似乎不是我想要的。在这一点上,float 或 int 并不重要。
  • 您必须在帖子中包含您尝试过的代码,并指出您的问题出在哪里。由于您是新用户,请阅读 StackOverflow 常见问题解答。
  • 您似乎在使用术语而不知道它们的含义。正态分布总是有无限范围的,标准正态分布是均值为零,标准差为一的正态分布。所以不可能用你的标准构造“一个”标准正态分布。

标签: python math random


【解决方案1】:

正如几位 cmet 提到的,这两个要求相互冲突:

我想生成一个介于 -1000 和 1000 之间的随机数

生成的数字应符合标准正态分布,平均为 x

因为标准normal distribution 具有无限域。如果您从正态分布中选择数字,那么您得到的值可能会大于 1000 或小于 -1000。相反,如果您采取任何措施将范围限制为 [-1000,1000],那么您将不会从正态分布中绘图。

一种选择是根据截断正态分布生成数字,这就像标准正态分布一样,只是概率在 [-1000,1000] 范围之外设置为零。最简单的方法是根据正态分布选择一个数字,如果超出所需范围,请重新选择。

SIGMA=10.0 # you can pick this value to be pretty much anything
def generate_number(average):
    x = random.normal_variate(average, SIGMA)
    while x > 1000 or x < -1000:
        x = random.normalvariate(average, SIGMA)
    return x

这里SIGMA 是正态分布的标准差,它控制着值的分布程度。如果SIGMA 很小并且average 不接近1000 或-1000,或者更准确地说:如果(1000-average)/SIGMA(1000+average)/SIGMA 都大于2 或3,那么这种方法将相当有效,因为它会通常第一次命中所需范围 [-1000,1000] 内的数字。但是,如果其中一个比率很小,比如大约 1 或更少,那么算法有时必须循环一次或两次。那可能不会有什么大不了的。 (如果你想避免它,你可以使用一些先进的技术,但我认为它不值得这么复杂。)

另一个选项,也就是你在问题中的示例代码所做的,是完全放弃使用正态分布的要求,并使用其他一些自然限制在一定范围内的概率分布。您的示例代码,相当于

random.triangular(-1000,1000,mode)

使用概率从 -1000 到 mode 线性增加,然后从 mode 到 1000 线性减少的分布。不过,问题在于 mode 是最大的值被选中的概率。它与所选数字的平均值不同。实际平均值是(min+max+mode)/3.,或者在你的情况下,因为min+max = 1000-1000 = 0,只是mode/3,所以如果你想生成具有指定平均值的数字,你必须使用

def generate_number(average):
    mode = 3*average
    if mode  < -1000 or mode > 1000:
        raise ValueError('Average cannot be satisfied: %f' % average)
    return random.normal_variate(-1000, 1000, mode)

请注意,使用此分布意味着您永远无法生成平均值小于-1000./3. 或大于1000./3. 的数字,除非您也相应地调整最小值或最大值。

【讨论】:

    【解决方案2】:
        normalvariate(self, mu, sigma) method of Random instance
        Normal distribution.
    
        mu is the mean, and sigma is the standard deviation.
    

    import random
    x= random.normalvariate(2,17)
    

    这里 2 是平均值,17 是标准差。如果您想线性缩放,您可以添加并乘以适当的值。

    【讨论】:

    • 为什么这是一个公认的答案???
    • @Jack_of_All_Trades 因为这就是答案。它用两行代码解决了平均和分布问题
    • 不,不!当 OP 想要 -1000 到 1000 之间的数字时,他如何提供标准偏差的值?
    • 这不能满足-1000 1000 的要求。
    • 从技术上讲,不可能满足极限要求和正态分布要求。
    【解决方案3】:

    标准正态分布的范围是无限的,在任何给定区间之外找到点的概率都是非零的。你可以使用triangular,记住平均值是(a + b + mode) / 3,所以triangular(a, b, 3*x - a - b)会得到你想要的:

    from random import triangular
    
    a = 0
    b = 10
    x = 3
    test = [triangular(a, b, 3*x - a - b) for _ in range(1000)]
    sum(test) / 1000.0
    # 3.006828109140065
    

    【讨论】:

    • 记住这不满足正态分布要求。
    • @Christian,OP 在编辑中添加了正态分布要求。因为这个要求与他的第一个限制要求不兼容,所以我只是保持我的答案不变并添加了一个注释。
    猜你喜欢
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    • 2015-10-28
    • 2022-07-14
    相关资源
    最近更新 更多