scipy Python中离散正态分布的快速方法

drkbr07n  于 8个月前  发布在  Python
关注(0)|答案(1)|浏览(87)

我尝试优化这段代码,以离散化正态分布的cdf(n个点,两点之间的delta等于10**c):

import numpy as np
from scipy.stats import norm
def norm_disc(m, s, n, c):
    cdf = norm(m, s).cdf
    bornes = np.arange(-0.5, n) * 10 ** c
    L = np.diff(cdf(bornes))
    L[0] += cdf(bornes[0])
    L[-1] += 1 - cdf(bornes[-1])
    return L

字符串
有没有办法让它更快?

f0brbegy

f0brbegy1#

通过将norm.cdf替换为scipy.special.ndtr,我观察到了~70的因子。SciPy分布有很多开销,但special.ndtr只是计算标准正态分布的CDF。我们可以转换输入以获得任何移位/缩放正态分布的正确结果。

import numpy as np
from scipy.stats import norm
from scipy.special import ndtr

def norm_disc1(m, s, n, c):
    cdf = norm(m, s).cdf
    bornes = np.arange(-0.5, n) * 10 ** c
    L = np.diff(cdf(bornes))
    L[0] += cdf(bornes[0])
    L[-1] += 1 - cdf(bornes[-1])
    return L

def norm_disc2(m, s, n, c):
    cdf = lambda x: ndtr((x-m)/s)
    bornes = np.arange(-0.5, n) * 10 ** c
    L = np.diff(cdf(bornes))
    L[0] += cdf(bornes[0])
    L[-1] += 1 - cdf(bornes[-1])
    return L

args = 1, 2, 100, 1
np.testing.assert_equal(norm_disc1(*args), norm_disc2(*args))
%timeit norm_disc1(*args)
# 1.59 ms ± 297 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit norm_disc2(*args)
# 22.5 µs ± 2.26 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

字符串

相关问题