python - 如何根据自定义概率密度函数(Python)生成随机数?

标签 python random scipy probability-density probability-distribution

我有一个包含随机变量 X 及其出现的分数的列表;所以如果我绘制这些,我会得到一个概率密度函数。我想知道如何使用这个概率密度函数来生成一些随机数?

我使用 scipy.interpolate.CubicSpline 来获取此数据的 Python 函数。如何使用此函数生成随机数?

最佳答案

为了重新表述您的问题,您已经提出了一个 pdf(“包含随机变量 X 及其出现的分数的列表”),并且想知道如何从具有该 pdf 的分布中抽取随机样本。 (我知道)有两种方法可以做到这一点,具体取决于您想要的正式程度。

TLDR:对于简单的情况,请使用 NumPy 实现,因为它干净、简单且快速。如果您因为使用更大的统计框架而需要更正式的版本,那么 SciPy 版本可能更适合。

SciPy

如果您希望它适合 SciPy 分发框架,那么您可以使用 rv_discrete 类并扩展它。在你的情况下,这看起来像:

from scipy.stats import rv_discrete

# these are your variables X
vals = [1, 2, 3]
# these are the fractions they occur
probs = [0.2, 0.5, 0.3]

# define discrete distribution
distrib = rv_discrete(values=(range(len(vals)), probs)) 

# sample 10 values from this distribution
distrib.rvs(size=10)
array([1, 0, 1, 2, 1, 1, 0, 1, 1, 1])

# distrib outputs indices in vals, not actual vals
[vals[x] for x in distrib.rvs(size=10)]
[3, 2, 3, 2, 2, 2, 1, 1, 2, 2]

以及快速速度测试以获得良好的测量结果:

%timeit [vals[x] for x in distrib.rvs(size=10000)]
2.34 ms ± 195 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

NumPy

正如评论中提到的,您可以直接使用 NumPy 使用 np.random.choice 函数。

import numpy as np
np.random.choice(vals, size=10, p=probs)
array([2, 2, 1, 2, 2, 2, 2, 3, 1, 2])

虽然它不是 SciPy 分发框架的一部分,但它简单干净,并且速度更快,如下所示:

%timeit np.random.choice(vals, size=10000, p=probs)
639 µs ± 204 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

NumPy 相对于 SciPy 的速度提升部分是由于它们生成采样过程中的伪随机数的方式不同。 NumPy 已将其默认 PRNG 进程升级为 PCG family随机数生成器,而 SciPy 仍在使用 Mersenne-Twister 。他们宣布了这个here如果你对它是如何工作的感到好奇,我写了一个简单的解释器 here 。还有更多详细信息 here专家之间。

通过将 NumPy PRNG 传递给 SciPy,我们可以看到速度提升的影响:

# default SciPy
distrib = rv_discrete(values=(range(len(vals)), probs))
%timeit [vals[x] for x in distrib.rvs(size=1000000)]
358 ms ± 204 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# SciPy but we pass NumPy's new PCG PRNG
np_seed = np.random.default_rng(123)
distrib = rv_discrete(values=(range(len(vals)), probs), seed=np_seed)
%timeit [vals[x] for x in distrib.rvs(size=1000000)]
221 ms ± 15.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

因此,使用 NumPy 的 PRNG 大约快 1.5 倍

关于python - 如何根据自定义概率密度函数(Python)生成随机数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69968051/

相关文章:

c# - 在 C# 中生成一个均分为另一个的随机数

python - 使用 python-future 解码 Python 2 `tempfile`

python - 无 类型不可迭代 (RecurrentTabularExplainer)

java - 为什么我在设置随机种子后总是得到相同的随机双倍?

java - 随机整数 - 正数和负数

python - scipy.sparse.csr_matrix.toarray() 的大量内存使用

python - 直方图上的瑞利分布曲线

Python Powell 最小化求解器 : type error - subtracting 'list' and 'list'

python - 设置日志级别会导致结构提示 'No handlers could be found for logger "ssh.transport"'

python 将列表格式化为逗号分隔的字符串