【问题标题】:Generate random number that follows a probability distribution生成遵循概率分布的随机数
【发布时间】:2021-04-22 07:00:37
【问题描述】:

我有一个从函数描述的概率分布,假设是一个高斯分布(系数为1/sqrt(pi),形成以下区域1):

import math
D = lambda x: pow(math.e, -pow(x,2)) / math.sqrt(math.pi)

前面的函数会绘制下图

如果我使用该高斯函数作为概率分布,我收到0 回复的概率将超过任何其他数字。

有没有办法生成遵循该分布的随机数?

【问题讨论】:

  • 确实有一个完整的book 专门讨论这个主题,所以我想说你的问题太宽泛了。甚至您的“假设...”高斯示例也有多种生成方式 - Box-Muller、极坐标法、ziggurat 法、接受/拒绝等等。

标签: python python-3.x random


【解决方案1】:

一种方法是使用 scipy.stats。

我们从 rv_continuous 继承并指定概率密度函数_pdf。接下来,我们使用继承的方法rvs()来抽取随机样本。

import math
from scipy.stats import rv_continuous


class MyRandomVariable(rv_continuous):
    def _pdf(self, x):
        return pow(math.e, -pow(x,2)) / math.sqrt(math.pi)
    
    
my_random_variable = MyRandomVariable()

samples = [my_random_variable.rvs() for i in range(10)]

【讨论】:

    【解决方案2】:

    内置的random库中有一些常见的随机分布。

    下面我按照高斯和对数正态生成了 1k 个随机数

    import random
    
    x = [random.gauss(10, 2) for r in range(1000)]
    
    y = [random.lognormvariate(10, 2) for x in range(1000)]
    

    【讨论】:

      【解决方案3】:

      考虑scipy.stats 库。来自正态分布的文档页面https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.norm.html

      from scipy.stats import norm # Import library
      r = norm.rvs(size=1000) # Draw 1000 random variates
      

      还要注意它是一个概率密度,所以抽到任何特定数字(包括0)的概率实际上是0。

      【讨论】:

        猜你喜欢
        • 2011-03-07
        • 1970-01-01
        • 1970-01-01
        • 2014-10-06
        • 2017-12-20
        • 2020-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多