Search code examples
pythonscipynormal-distribution

How to calculate the inverse of the normal cumulative distribution function in python?


How do I calculate the inverse of the cumulative distribution function (CDF) of the normal distribution in Python?

Which library should I use? Possibly scipy?


Solution

  • NORMSINV (mentioned in a comment) is the inverse of the CDF of the standard normal distribution. Using scipy, you can compute this with the ppf method of the scipy.stats.norm object. The acronym ppf stands for percent point function, which is another name for the quantile function.

    In [20]: from scipy.stats import norm
    
    In [21]: norm.ppf(0.95)
    Out[21]: 1.6448536269514722
    

    Check that it is the inverse of the CDF:

    In [34]: norm.cdf(norm.ppf(0.95))
    Out[34]: 0.94999999999999996
    

    By default, norm.ppf uses mean=0 and stddev=1, which is the "standard" normal distribution. You can use a different mean and standard deviation by specifying the loc and scale arguments, respectively.

    In [35]: norm.ppf(0.95, loc=10, scale=2)
    Out[35]: 13.289707253902945
    

    If you look at the source code for scipy.stats.norm, you'll find that the ppf method ultimately calls scipy.special.ndtri. So to compute the inverse of the CDF of the standard normal distribution, you could use that function directly:

    In [43]: from scipy.special import ndtri
    
    In [44]: ndtri(0.95)
    Out[44]: 1.6448536269514722
    

    ndtri is much faster than norm.ppf:

    In [46]: %timeit norm.ppf(0.95)
    240 µs ± 1.75 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
    
    In [47]: %timeit ndtri(0.95)
    1.47 µs ± 1.3 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)