2009-04-30 75 views

Respuesta

18

Adaptado de aquí 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

Dado que std lib implementa math.erf(), no hay necesidad de una implementación sep. – Marc

85

He aquí un ejemplo:

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

Si necesita la CDF inversa:

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

Además, puede especificar la media (loc) y la varianza (escala) como parámetros. por ejemplo, d = norma (loc = 10.0, escala = 2.0); d.cdf (12.0); Detalles aquí: http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.stats.norm.html – Irvan

+5

@Irvan, el parámetro de escala es en realidad la desviación estándar, NO la varianza. – qkhhly

+1

¿Por qué scipy los nombra como 'loc' y' scale'? Usé 'help (norm.ppf)', pero ¿qué diablos son 'loc' y' scale'? Necesito una ayuda para la ayuda. – javadba

12

Para aprovechar el ejemplo de Desconocido, el equivalente del pitón de la función normdist() implementada en muchas bibliotecas sería:

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

A medida que Google da esta respuesta para la búsqueda pdf NetLogo, aquí está la versión NetLogo del código Python anterior

 

    ;; 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 pregunta es sobre Python, no NetLogo. Esta respuesta no debería estar aquí. Y por favor no edite la pregunta para cambiar su significado. – interjay

+0

Soy consciente de que esta no es la manera preferida, pero supongo que es más útil de esta manera, ya que las personas son dirigidas a esta página por google (actualmente ...) – platipodium

22

Puede ser demasiado tarde para responder a la pregunta, pero desde que Google sigue líder aquí, decido escribir mi solución aquí.

es decir, desde Python 2.7, la biblioteca math ha integrado la función de error math.erf(x)

La función erf() se puede utilizar para calcular funciones estadísticas tradicionales, tales como la distribución acumulativa normal estándar:

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

Ref:

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

Esto era exactamente lo que estaba buscando. Si alguien más que yo se pregunta cómo se puede usar para calcular el "porcentaje de datos que se encuentra dentro de la distribución estándar", bueno: 1 - (1 - phi (1)) * 2 = 0,6827 ("68% de los datos dentro de 1 estándar desviación") –

7

respuesta de Alex muestra una solución para la distribución normal estándar (media = 0, desviación estándar = 1). Si tiene distribución normal con mean y std (que es sqr(var)) y se desea calcular:

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) 

Leer más sobre cdf here e implementación scipy de distribución normal con muchas fórmulas here.

Cuestiones relacionadas