如何计算累积正态分布?


99

我正在寻找Numpy或Scipy(或任何严格的Python库)中的函数,该函数将为我提供Python中的累积正态分布函数。

Answers:


125

这是一个例子:

>>> from scipy.stats import norm
>>> norm.cdf(1.96)
0.9750021048517795
>>> norm.cdf(-1.96)
0.024997895148220435

换句话说,大约95%的标准法线间隔位于两个标准偏差之内,以标准平均值零为中心。

如果需要逆CDF:

>>> norm.ppf(norm.cdf(1.96))
array(1.9599999999999991)

9
另外,您可以将平均值(位置)和方差(比例)指定为参数。例如d = norm(loc = 10.0,scale = 2.0); d.cdf(12.0); 此处的详细信息:docs.scipy.org/doc/scipy-0.14.0/reference/genic/…–
Irvan

6
@Irvan,比例参数实际上是标准偏差,而不是方差。
2015年

2
scipy为什么将这些命名为locand scale?我用了help(norm.ppf),但那么到底什么是locscale-需要的帮助帮助..
javadba

2
@javadba-位置和比例是统计中的更通用术语,用于参数化广泛的分布。对于正态分布,它们与均值和sd对齐,而对于其他分布则不是。
Michael Ohlrogge

1
@MichaelOhlrogge。谢谢!这是NIST的网页,进一步解释了itl.nist.gov/div898/handbook/eda/section3/eda364.htm
javadba

40

回答这个问题可能为时已晚,但是由于Google仍然领导这里的人们,因此我决定在此处编写解决方案。

也就是说,自Python 2.7起,该math库集成了error函数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

误差函数和标准正态分布函数有何关系?


3
这正是我想要的。如果我以外的人想知道如何将其用于计算“标准分布内的数据百分比”,那么:1-(1-phi(1))* 2 = 0.6827(“ 1个标准内68%的数据偏差”)
汉尼斯·兰德霍尔姆

1
对于一般的正态分布,它将为def phi(x, mu, sigma): return (1 + erf((x - mu) / sigma / sqrt(2))) / 2
Bernhard Barker

19

从这里改编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))

3
由于标准库实现math.erf(),因此无需单独执行。
Marc 2016年

我找不到答案,这些数字从哪里来?
TmSmth

15

以Unknown的示例为基础,在许多库中实现的功能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

15

从开始Python 3.8,标准库将NormalDist对象作为statistics模块的一部分提供。

对于给定的均值()和标准差(),它可用于获取累积分布函数cdf-随机样本X小于或等于x的概率):musigma

from statistics import NormalDist

NormalDist(mu=0, sigma=1).cdf(1.96)
# 0.9750021048517796

对于标准正态分布mu = 0sigma = 1)可以简化:

NormalDist().cdf(1.96)
# 0.9750021048517796

NormalDist().cdf(-1.96)
# 0.024997895148220428

9

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的执行正态分布的许多公式在这里


2

从上方拍摄:

from scipy.stats import norm
>>> norm.cdf(1.96)
0.9750021048517795
>>> norm.cdf(-1.96)
0.024997895148220435

对于两尾测试:

Import numpy as np
z = 1.96
p_value = 2 * norm.cdf(-np.abs(z))
0.04999579029644087


-9

当Google针对搜索netlogo pdf提供此答案时,这是上述python代码的netlogo版本

    ;; 正态分布累积密度函数
    报告normcdf [x mu sigma]
        让TX-亩
        让y 0.5 * erfcc [-t /(sigma * sqrt 2.0)]
        如果(y> 1.0)[设置y 1.0]
        报告y
    结束

    ;; 正态分布概率密度函数
    报告normpdf [x mu sigma]
        设u =(x-mu)/ abs sigma
        令y = 1 /(sqrt [2 * pi] * abs sigma)* exp(-u * u / 2.0)
        报告y
    结束

    ;; 互补误差函数
    报告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)[报告r] [报告2.0-r]
    结束


6
问题是关于Python,而不是NetLogo。这个答案不应该在这里。并且请不要编辑问题以更改其含义。
interjay 2012年

我知道这不是首选的方式,但是我猜这种方式最有用,因为人们被google引导到此页面(当前...)
platipodium
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.