2009-04-30 26 views

risposta

18

Adattato da qui 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)) 
+1

Poiché la std lib implementa math.erf(), non è necessaria un'implementazione sep. – Marc

85

Ecco un esempio:

>>> from scipy.stats import norm 
>>> norm.cdf(1.96) 
array(0.97500210485177952) 

Se avete bisogno della CDF inversa:

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

Inoltre, è possibile specificare la media (loc) e la varianza (scala) come parametri. per esempio, d = norma (loc = 10.0, scale = 2.0); d.cdf (12.0); Dettagli qui: http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.stats.norm.html – Irvan

+5

@Irvan, il parametro di scala è in realtà la deviazione standard, NON la varianza. – qkhhly

+1

Perché scipy le chiama "loc" e "scale"? Ho usato 'help (norm.ppf)' ma poi cosa diamine sono 'loc' e' scale' - ho bisogno di un aiuto per l'aiuto .. – javadba

12

Per sviluppare l'esempio di Unknown, l'equivalente Python la funzione normdist() implementata in molte librerie sarebbe:

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 
-5

Come Google dà questa risposta per la ricerca NetLogo pdf, ecco la versione NetLogo del codice Python sopra

 

    ;; Normal distribution cumulative density function 
    to-report normcdf [x mu sigma] 
     let t x - mu 
     let y 0.5 * erfcc [ - t/(sigma * sqrt 2.0)] 
     if (y > 1.0) [ set y 1.0 ] 
     report y 
    end 

    ;; Normal distribution probability density function 
    to-report normpdf [x mu sigma] 
     let u = (x - mu)/abs sigma 
     let y = 1/(sqrt [2 * pi] * abs sigma) * exp (- u * u/2.0) 
     report y 
    end 

    ;; Complementary error function 
    to-report erfcc [x] 
     let z abs x 
     let t 1.0/(1.0 + 0.5 * z) 
     let r t * 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] 
    end 

+5

La domanda riguarda Python, non NetLogo. Questa risposta non dovrebbe essere qui. E per favore non modificare la domanda per cambiarne il significato. – interjay

+0

Sono consapevole che questo non è il modo preferito, ma immagino che sia molto utile in questo modo dato che le persone sono indirizzate a questa pagina da google (attualmente ...) – platipodium

22

Potrebbe essere troppo tardi per rispondere alla domanda, ma dal momento che Google ancora contatti gente qui, decido di scrivere la mia soluzione qui.

Cioè, dato che Python 2.7, la libreria math ha integrato la funzione di errore math.erf(x)

La funzione erf() può essere usato per calcolare funzioni statistiche tradizionali come la cumulativa della distribuzione normale standard:

from math import * 
def phi(x): 
    #'Cumulative distribution function for the standard normal distribution' 
    return (1.0 + erf(x/sqrt(2.0)))/2.0 

Rif:

https://docs.python.org/2/library/math.html

https://docs.python.org/3/library/math.html

How are the Error Function and Standard Normal distribution function related?

+1

Questo era esattamente quello che stavo cercando. Se qualcun altro oltre a me si chiede come questo possa essere utilizzato per calcolare "la percentuale di dati che si trova all'interno della distribuzione standard", beh: 1 - (1 - phi (1)) * 2 = 0,6827 ("68% dei dati all'interno di 1 standard deviazione") –

7

risposta di Alex mostra una soluzione per la distribuzione normale standard (media = 0, deviazione standard = 1). Se si dispone di una distribuzione normale con mean e std (che è sqr(var)) e si vuole calcolare:

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) 

Per saperne di più cdf here e SciPy implementazione di distribuzione normale con molte formule here.

Problemi correlati