Python 对于相关分布抽样,是否有一种快速替代scipy _norm_pdf的方法?

Python 对于相关分布抽样,是否有一种快速替代scipy _norm_pdf的方法?,python,numpy,scipy,distribution,montecarlo,Python,Numpy,Scipy,Distribution,Montecarlo,我已经为蒙特卡罗模拟拟合了一系列SciPy连续分布,并希望从这些分布中获取大量样本。但是,我希望能够采集相关样本,以便Ith样本从每个分布中提取第90个百分位 在这样做的过程中,我发现了SciPy性能中的一个怪癖: #非常快速地找到许多长度为n的不相关样本 发行版道具中的形状、位置、比例: sp.stats.norm.rvs(*形状,位置=位置,比例=比例,尺寸=n) #Verrryyyy获取长度为n的相关样本的慢方法 相关=np.随机.均匀(大小=n) 发行版道具中的形状、位置、比例: sp.

我已经为蒙特卡罗模拟拟合了一系列SciPy连续分布,并希望从这些分布中获取大量样本。但是,我希望能够采集相关样本,以便
I
th样本从每个分布中提取第90个百分位

在这样做的过程中,我发现了SciPy性能中的一个怪癖:

#非常快速地找到许多长度为n的不相关样本
发行版道具中的形状、位置、比例:
sp.stats.norm.rvs(*形状,位置=位置,比例=比例,尺寸=n)
#Verrryyyy获取长度为n的相关样本的慢方法
相关=np.随机.均匀(大小=n)
发行版道具中的形状、位置、比例:
sp.stats.norm.ppf(相关,*形状,位置=位置,比例=比例)
关于这一点的大多数结果都声称,这些SciPy发行版的速度慢是由类型检查等包装造成的。然而,当我分析代码时,大部分时间都花在底层的数学函数
[\u continuous\u distns.py:179(\u norm\u pdf)]
上。此外,它以
n
为尺度,这意味着它在内部循环通过每个元素

SciPy几乎似乎建议子类应该覆盖它以提高性能,但我将monkeypatch插入SciPy以加速其ppf似乎很奇怪。我会根据ppf公式计算法线,但我也会使用对数法线和扭曲法线,这更难实现


那么,Python中计算正态、对数正态和偏态正态分布的快速ppf的最佳方法是什么?或者更广泛地说,从几个这样的分布中获取相关样本?

如果您只需要正常的
ppf
,它的速度如此之慢确实令人费解,但您可以使用
scipy.special.erfinv

x = np.random.uniform(0,1,100)
np.allclose(special.erfinv(2*x-1)*np.sqrt(2),stats.norm().ppf(x))
# True
timeit(lambda:stats.norm().ppf(x),number=1000)
# 0.7717257660115138
timeit(lambda:special.erfinv(2*x-1)*np.sqrt(2),number=1000)
# 0.015020604943856597
编辑:

lognormal
triangle
也是直截了当的:

c = np.random.uniform()

np.allclose(np.exp(c*special.erfinv(2*x-1)*np.sqrt(2)),stats.lognorm(c).ppf(x))
# True

np.allclose(((1-np.sqrt(1-(x-c)/((x>c)-c)))*((x>c)-c))+c,stats.triang(c).ppf(x))
# True

不幸的是,我不太熟悉歪正态分布。

最终,这个问题是由于我使用了分布而引起的。倾斜法线的ppf实际上没有封闭形式的分析定义,因此为了计算ppf,它回到了
scipy.continuous_rv
的数值近似,这涉及迭代计算cdf,并使用cdf将ppf值归零。倾斜法线pdf是法线pdf和法线cdf的乘积,因此这种数值近似多次称为法线的pdf和cdf。这就是为什么当我分析代码时,问题似乎是正态分布,而不是SKU正态分布。这个问题的另一个答案是可以通过跳过类型检查来节省时间,但实际上并没有对运行时增长产生影响,只是对small-n运行时产生了影响

为了解决这个问题,我用分布替换了斜正态分布。它比正态分布多2个自由参数,因此可以有效地拟合不同类型的偏斜和峰度。它支持所有实数,并且它有一个封闭形式的ppf定义,在SciPy中有一个快速实现。下面你可以看到我从第10、50和90百分位拟合的Johnson-SU分布示例


如果我理解正确,第二个选项对应于分布右半部分的数字(因为[0,1]中有统一)。我很惊讶第一个选项没有实现为
ppf(统一(-1,1,size=n),loc=loc,scale=scale)
您是否仅限于scipy?也许概率编程语言的实现速度更快?谢谢!这是一个很好的答案,但我希望我可以避免重新实现我使用的所有发行版。还有对数法线,斜法线和三角形。看起来这可能是唯一的选择,但这似乎仍然是一个在未来很好解决的问题library@NealJMD不幸的是,请参阅更新,它不是您所需要的全部,但几乎是。