使用 numpy.random.normal 时如何指定上限和下限

新手上路,请多包涵

我希望能够从只落在 0 和 1 之间的正态分布中选取值。在某些情况下,我希望能够基本上只返回一个完全随机的分布,而在其他情况下,我想返回落在高斯的形状。

目前我正在使用以下功能:

 def blockedgauss(mu,sigma):
    while True:
        numb = random.gauss(mu,sigma)
        if (numb > 0 and numb < 1):
            break
    return numb

它从正态分布中选择一个值,如果它落在 0 到 1 的范围之外则丢弃它,但我觉得必须有更好的方法来做到这一点。

原文由 Catherine Georgia 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.6k
3 个回答

听起来您想要 截断的正态分布。使用 scipy,您可以使用 scipy.stats.truncnorm 从这样的分布中生成随机变量:

 import matplotlib.pyplot as plt
import scipy.stats as stats

lower, upper = 3.5, 6
mu, sigma = 5, 0.7
X = stats.truncnorm(
    (lower - mu) / sigma, (upper - mu) / sigma, loc=mu, scale=sigma)
N = stats.norm(loc=mu, scale=sigma)

fig, ax = plt.subplots(2, sharex=True)
ax[0].hist(X.rvs(10000), normed=True)
ax[1].hist(N.rvs(10000), normed=True)
plt.show()

在此处输入图像描述

上图显示截断正态分布,下图显示具有相同均值 mu 和标准差 sigma 的正态分布。

原文由 unutbu 发布,翻译遵循 CC BY-SA 4.0 许可协议

我在寻找一种方法来返回从零到 1 之间截断的正态分布(即概率)中采样的一系列值时遇到了这篇文章。为了帮助遇到同样问题的其他人,我只想指出 scipy.stats.truncnorm 具有内置功能“.rvs”。

因此,如果您想要 100,000 个均值为 0.5 且标准差为 0.1 的样本:

 import scipy.stats
lower = 0
upper = 1
mu = 0.5
sigma = 0.1
N = 100000

samples = scipy.stats.truncnorm.rvs(
          (lower-mu)/sigma,(upper-mu)/sigma,loc=mu,scale=sigma,size=N)

这给出了与 numpy.random.normal 非常相似的行为,但在所需的范围内。使用内置函数比循环收集样本要快得多,尤其是对于大的 N 值。

原文由 Greg Alushin 发布,翻译遵循 CC BY-SA 3.0 许可协议

新手上路,请多包涵

有两种方法来限制np.random.normal的上下限
第一种是从使用np.interp来缩放生成的正太数列到规定的上下限,当然额外的参数需要自行处理

    start_time = datetime.strptime(f'{nowr} 17:45',"%Y-%m-%d %H:%M")
    end_time = datetime.strptime(f'{nowr} 18:45',"%Y-%m-%d %H:%M")
    
    total_seconds = (end_time - start_time).seconds
    mean = total_seconds / 2    
    std_dev = total_seconds / 10     # 标准差可以根据需要调整
    random_seconds = np.random.normal(loc=mean, scale=std_dev, size=num)
    random_seconds = np.interp(random_seconds,(min(random_seconds),max(random_seconds)),(0.05*total_seconds,0.95*total_seconds))        # 值域缩放避免越界
    random_times = [start_time + timedelta(seconds=int(s)) for s in random_seconds]

第二种 手动计算规定边界的平均值,再计算缩放比,递归一下生成的每个数,处理每个数进行缩放。(没写)

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题