NumPy,如何生成符合正态分布的整数集合?

7
什么是使用numpy生成正态分布整数集的最佳方法?我知道可以通过以下方式获得浮点数:
In [31]: import numpy as np

In [32]: import matplotlib.pyplot as plt

In [33]: plt.hist(np.random.normal(250, 1, 100))
Out[33]: 
(array([  2.,   5.,   9.,  10.,  19.,  21.,  13.,  10.,   6.,   5.]),
 array([ 247.52972483,  247.9913017 ,  248.45287858,  248.91445546,
         249.37603233,  249.83760921,  250.29918608,  250.76076296,
         251.22233984,  251.68391671,  252.14549359]),
 <a list of 10 Patch objects>)

histogram


除非您真的需要高精度,否则我建议您只需将浮点数四舍五入。 - user707650
好的,就像这样:np.random.normal(250, 1, 100).round(0) - tbc
如果您需要实际的整数:np.random.normal(250, 1, 100).round().astype(np.int)。(默认情况下,np.round 的值为0)。 - user707650
你可以在浮点数的分布图上叠加整数分布图,看看是否满意。 - user707650
@Evert 在这种情况下,“高准确性”是什么意思? 根据定义,正态分布是连续的。 - ali_m
2个回答

8

二项分布是正态分布的良好离散近似。换句话说,

Binomial(n, p) ~ Normal(n*p, sqrt(n*p*(1-p)))

所以你可以这样做

import numpy as np
import matplotlib.pyplot as plt
from math import sqrt

bi = np.random.binomial(n=100, p=0.5, size=10000)
n = np.random.normal(100*0.5, sqrt(100*0.5*0.5), size=10000)

plt.hist(bi, bins=20, normed=True);
plt.hist(n, alpha=0.5, bins=20, normed=True);
plt.show();

enter image description here


非常好,谢谢。我想这让我意识到,我(目前)并不太关心分布的具体细节,而更感兴趣的是如何获得符合任何分布的整数集合,而不是numpy.random.randint(..)提供的默认(均匀)分布。 - tbc
这不会生成任何小于30或大于70的样本吗? - André Fratelli
我在使用这个过程中观察到的是,当从正态分布转换为二项式分布时,正态分布的相对标准偏差必须小于或等于正态分布的均值的sqrt(1/mean)。 - Dominik

6
我发现这篇文章有些晚了,但如果你想生成一个任意分布的整数集合,可以使用与之相关联的分布的反函数CDF(百分位数),例如从scipy.stats中获取,并从中均匀地绘制百分位数。然后将其转换为整数即可完成:
from scipy.stats import norm
import matplotlib.pyplot as plt
import numpy as np
# Generate 10000 normal random integers with specified mean (loc) and std (scale).
draw = norm.ppf(np.random.random(10000), loc=0, scale=100).astype(int)
plt.hist(draw, bins=20)

enter image description here

scipy.stats中连续分布的列表可以在这里找到, 离散分布的列表可以在这里找到

尽管对于上面的例子,您可以直接从所需的分布中进行抽样并转换为整数,但这种方法(从CDF中均匀采样百分位数)的好处是它适用于任何分布,甚至是只能从数据数值定义的分布!


1
非常好 - 隐藏的宝石! - undefined

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