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

normal-distribution, python, 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)

Problem

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?

Original source