如何计算Python中的累积正态分布
我在Numpy或Scipy(或任何严格的Python库)中寻找一个函数,它会给我Python中的累积正态分布函数。
这是一个例子:
>>> from scipy.stats import norm >>> norm.cdf(1.96) array(0.97500210485177952)
如果你需要反CDF:
>>> norm.ppf(norm.cdf(1.96)) array(1.9599999999999991)
回答这个问题可能为时已晚,但由于Google仍然在这里领导人员,所以我决定在这里写下我的解决scheme。
也就是说,自Python 2.7以来, math库已经集成了错误函数math.erf(x)
erf()函数可以用来计算传统的统计函数,如累积的标准正态分布:
from math import * def phi(x): #'Cumulative distribution function for the standard normal distribution' return (1.0 + erf(x / sqrt(2.0))) / 2.0
参考:
https://docs.python.org/2/library/math.html
https://docs.python.org/3/library/math.html
误差函数和标准正态分布函数如何相关?
从这里改编http://mail.python.org/pipermail/python-list/2000-June/039873.html
from math import * def erfcc(x): """Complementary error function.""" z = abs(x) t = 1. / (1. + 0.5*z) r = t * exp(-z*z-1.26551223+t*(1.00002368+t*(.37409196+ t*(.09678418+t*(-.18628806+t*(.27886807+ t*(-1.13520398+t*(1.48851587+t*(-.82215223+ t*.17087277))))))))) if (x >= 0.): return r else: return 2. - r def ncdf(x): return 1. - 0.5*erfcc(x/(2**0.5))
为了build立在未知的例子,许多库中实现的函数normdist()的Python等价物将是:
def normcdf(x, mu, sigma): t = x-mu; y = 0.5*erfcc(-t/(sigma*sqrt(2.0))); if y>1.0: y = 1.0; return y def normpdf(x, mu, sigma): u = (x-mu)/abs(sigma) y = (1/(sqrt(2*pi)*abs(sigma)))*exp(-u*u/2) return y def normdist(x, mu, sigma, f): if f: y = normcdf(x,mu,sigma) else: y = normpdf(x,mu,sigma) return y
Alex的答案显示了标准正态分布的解(平均值= 0,标准偏差= 1)。 如果你用mean
和std
(这是sqr(var)
)有正态分布,并且你想计算:
from scipy.stats import norm # cdf(x < val) print norm.cdf(val, m, s) # cdf(x > val) print 1 - norm.cdf(val, m, s) # cdf(v1 < x < v2) print norm.cdf(v2, m, s) - norm.cdf(v1, m, s)
在这里阅读更多关于cdf的内容,并以许多公式在这里以scipy实现正态分布。
由于Google为searchnetlogo pdf提供了这个答案,下面是上述python代码的netlogo版本
;; 正态分布累积密度函数 报告normcdf [x mu sigma] 让tx - 亩 让y 0.5 * erfcc [ - t /(sigma * sqrt 2.0)] 如果(y> 1.0)[set y 1.0] 报告y 结束 ;; 正态分布概率密度函数 to-report normpdf [x mu sigma] 让u =(x - mu)/ abs sigma 令y = 1 /(sqrt [2 * pi * abs sigma)* exp(-u * u / 2.0) 报告y 结束 ;; 补充错误function 要报告erfcc [x] 让z abs x 让t 1.0 /(1.0 + 0.5 * z) 令rt * exp(-z * z -1.26551223 + t *(1.00002368 + t *(0.37409196 + t *(0.09678418 + t *(-0.18628806 + t *(.27886807 + t *(-1.13520398 + t *(1.48851587 + t *( - 0.82215223 + t * .17087277))))))))) ifelse(x> = 0)[report r] [report 2.0 - r] 结束