Python 如何从截断正态分布中获得最佳样本?

Python 如何从截断正态分布中获得最佳样本?,python,numpy,scipy,Python,Numpy,Scipy,我已经做了一些搜索,但我似乎无法找到一种合理的方法从截断正态分布中取样 没有截断,我正在做: samples=[np.random.normal(loc=x,scale=d)表示zip(x,d)中的(x,d)] X和D是浮动列表 目前,我正在实施截断: def truncnorm(位置、刻度、界限): s=np.随机.正常(位置,刻度) 如果s>边界[1]: 返回边界[1] elif sbounds[1]:返回truncnorm(loc,scale,bounds)即,如果您落在外部,请重试。根

我已经做了一些搜索,但我似乎无法找到一种合理的方法从截断正态分布中取样

没有截断,我正在做:

samples=[np.random.normal(loc=x,scale=d)表示zip(x,d)中的(x,d)]
X
D
是浮动列表

目前,我正在实施截断:

def truncnorm(位置、刻度、界限):
s=np.随机.正常(位置,刻度)
如果s>边界[1]:
返回边界[1]
elif s
bounds
是元组列表
(最小值,最大值)


这种方法感觉有点尴尬,所以我想知道是否有更好的方法?

返回边界以外样本的边界值,将导致太多样本落在边界上。这并不代表实际的分布情况。边界上的值需要被拒绝并替换为新样本。这种代码可以是:

def测试标准(位置、刻度、界限):
尽管如此:
s=np.随机.正常(位置,刻度)

如果bounds[0]返回其外部样本的边界值,将导致太多样本落在边界上。这并不代表实际的分布情况。边界上的值需要被拒绝并替换为新样本。这种代码可以是:

def测试标准(位置、刻度、界限):
尽管如此:
s=np.随机.正常(位置,刻度)

如果边界[0]很好,那么您所展示的并不是通常所说的截断正态分布。相反,它是一个截断正态分布与离散分布的混合物,离散分布的点质量在边界[0]处,另一点质量在边界[1]处。要获得截断法线,需要
if s>bounds[1]:返回truncnorm(loc,scale,bounds)
即,如果您落在外部,请重试。根据边界的不同,您可能需要多次尝试。如果大部分质量位于边界之间,则可以重试。但是,如果边界可能排除大部分质量,您可能需要不同的方法。不同的方法是反转cdf,cdf是不受约束cdf的缩放版本(缩放因子等于边界之间的质量)。这将是一个涉及erf的表达式。我不知道逆erf是否是numpy/scipy中可用的函数之一,但如果不是,您可以通过对分或类似的简单方法将其反转。您看到了吗?它与您实现的并不完全相同,因为(正如@RobertDodier所指出的),您的分布在边界上有点质量。通常情况下,边界上没有这些点质量。@WarrenWeckesser我查看了scipy函数,但我不知道如何设置范围。Dupe of?嗯,你所展示的不是通常所说的截断正态分布。相反,它是一个截断正态分布与离散分布的混合物,离散分布的点质量在边界[0]处,另一点质量在边界[1]处。要获得截断法线,需要
if s>bounds[1]:返回truncnorm(loc,scale,bounds)
即,如果您落在外部,请重试。根据边界的不同,您可能需要多次尝试。如果大部分质量位于边界之间,则可以重试。但是,如果边界可能排除大部分质量,您可能需要不同的方法。不同的方法是反转cdf,cdf是不受约束cdf的缩放版本(缩放因子等于边界之间的质量)。这将是一个涉及erf的表达式。我不知道逆erf是否是numpy/scipy中可用的函数之一,但如果不是,您可以通过对分或类似的简单方法将其反转。您看到了吗?它与您实现的并不完全相同,因为(正如@RobertDodier所指出的),您的分布在边界上有点质量。通常在边界上没有这些点质量。@WarrenWeckesser我查看了scipy函数,但不知道如何设置范围。Dupe of?
X = np.array(X)
D = np.array(D)
bounds = np.array(bounds)
samples = scipy.stats.truncnorm.rvs((bounds[:, 0] - X) / D, (bounds[:, 1] - X) / D, loc=X, scale=D)