Skip to main content
 首页 » 编程设计

python之从截断的正态分布中抽样

2025年05月04日23虾米姐

如何从经过裁剪的正态分布中采样?

我想从 N(0, 1) 中采样。但我希望值来自 [-1, +1]。我不能应用 np.clip,因为这会增加 -1 和 +1 的概率。我可以进行随机裁剪,但无法保证它会超出范围。

#standard 
s = np.random.normal(0, 1, [10,10]) 
s = np.clip(s) 
 
#stochastic 
for j in range(10) 
    edge1 = np.where(s[j] >= 1.)[0] 
    edge2 = np.where(s[j] <= -1)[0] 
 
    if edge1.shape[0] > 0: 
        rand_el1 = np.random.normal(0, 1, size=(1, edge1.shape[0]))  
        s[j,edge1] = rand_el1 
    if edge2.shape[0] > 0: 
        rand_el2 = np.random.normal(0, 1, size=(1, edge2.shape[0]))                             
        s[j,edge2] = rand_el2 

请您参考如下方法:

scipy 库将截断正态分布实现为 scipy.stats.truncnorm .在您的情况下,您可以使用 sample = truncnorm.rvs(-1, 1, size=sample_size)。

例如,

In [55]: import matplotlib.pyplot as plt 
 
In [56]: from scipy.stats import truncnorm, norm 

从截断为 [-1, 1] 的正态分布中抽样 100000 个点:

In [57]: sample = truncnorm.rvs(-1, 1, size=100000) 

制作直方图,绘制理论 PDF 曲线。可以使用 truncnorm.pdf 或 norm.pdf 的缩放版本计算 PDF。

In [58]: _ = plt.hist(sample, bins=51, normed=True, facecolor='g', edgecolor='k', alpha=0.4) 
 
In [59]: x = np.linspace(-1, 1, 101) 
 
In [60]: plt.plot(x, truncnorm.pdf(x, -1, 1), 'k', alpha=0.4, linewidth=5) 
Out[60]: [<matplotlib.lines.Line2D at 0x11f78c160>] 
 
In [61]: plt.plot(x, norm.pdf(x)/(norm.cdf(1) - norm.cdf(-1)), 'k--', linewidth=1) 
Out[61]: [<matplotlib.lines.Line2D at 0x11f779f60>] 

这是情节: