Use densities and CDFs to work with exponential, normal and gamma distributions for measurements and waiting times.
Why this matters
Lengths, concentrations, temperatures, lifetimes and waiting times are not counts: they can take any value in a range. You cannot list their probabilities one by one, so continuous random variables are described by a density instead. Three continuous distributions cover a huge share of everyday work: the exponential for waiting times, the normal for measurements, and the gamma for totals of waiting times and skewed positive quantities.
Density and CDF
A probability density function (PDF) f(x) is a curve whose area gives probability:
P(a ≤ X ≤ b) = area under f(x) between a and b
total area under f(x) = 1
Two consequences surprise people:
P(X = 2.5)is exactly 0 for a continuous variable. Only intervals have probability.- A density value can be larger than 1 (a very narrow curve is very tall). Density is not probability.
The cumulative distribution function (CDF) F(x) = P(X ≤ x) is usually what you compute with, because
P(a < X ≤ b) = F(b) - F(a)
P(X > x) = 1 - F(x)
The exponential distribution
The time between events in a Poisson process (lesson 2) is exponential with rate λ:
f(x) = λ e^(-λx) F(x) = 1 - e^(-λx) x ≥ 0
E[X] = 1/λ SD(X) = 1/λ
Worked example. Calls arrive at 3 per hour, so λ = 3 per hour and the mean gap is 20 minutes. The chance of waiting more than 30 minutes (0.5 h) for the next call is e^(-3 × 0.5) = e^(-1.5) ≈ 0.223.
Worked example. A component has a mean life of 1,000 hours (λ = 0.001 per hour). P(fails before 500 h) = 1 - e^(-0.5) ≈ 0.393.
The exponential is memoryless: P(X > s + t | X > s) = P(X > t). A part that has survived 800 hours is, under this model, as good as new. That is realistic for random shocks and electronic failures but wrong for parts that wear out, which is why reliability engineers also use the Weibull distribution.
The normal distribution
You met the normal in Statistics Fundamentals. Here is the tool for computing with it exactly. For X ~ Normal(μ, σ), standardise with z = (x - μ) / σ, then use the standard normal CDF, which Python can build from the error function:
Φ(z) = 0.5 * (1 + erf(z / sqrt(2)))
Worked example. Test scores are Normal(100, 15). The share between 85 and 130 is Φ(2) - Φ(-1) ≈ 0.977 - 0.159 = 0.819.
import math
from statistics import NormalDist
def normal_cdf(x, mu, sigma):
return 0.5 * (1 + math.erf((x - mu) / (sigma * math.sqrt(2))))
print(normal_cdf(130, 100, 15) - normal_cdf(85, 100, 15)) # 0.8186
print(NormalDist(100, 15).cdf(130) - NormalDist(100, 15).cdf(85)) # same
statistics.NormalDist also has inv_cdf for the reverse question: "what score marks the top 5%?" (NormalDist(100, 15).inv_cdf(0.95) ≈ 124.7).
The gamma distribution
Add up k independent exponential waiting times, each with rate λ, and the total follows a gamma distribution with shape k and rate λ:
E[X] = k / λ Var(X) = k / λ^2
The time until the 3rd call at 3 calls per hour has mean 3/3 = 1 hour and SD sqrt(3)/3 ≈ 0.58 hours. The gamma is also a flexible model for any positive, right-skewed quantity: claim sizes, rainfall totals, reaction times. It allows non-integer shapes too, and with k = 1 it is the exponential.
In libraries
scipy.stats provides all three with the same interface (pdf, cdf, ppf for the inverse CDF, rvs for random draws):
from scipy import stats
stats.expon(scale=1/3).sf(0.5) # P(X > 0.5) = 0.223; scale is 1/rate
stats.norm(100, 15).cdf(130)
stats.gamma(a=3, scale=1/3).mean() # 1.0
Watch the parameterisation: SciPy and NumPy use scale = 1/rate for the exponential and gamma. Mixing up rate and scale is the most common error in this area.
Common mistakes
- Treating density as probability. Only areas are probabilities.
- Rate vs scale.
rng.exponential(3)in NumPy has mean 3, not rate 3. - Using the exponential for wear-out. Memorylessness rarely fits mechanical parts.
- Assuming everything is normal. Waiting times and claim sizes are skewed; look at a histogram first.
Recap
- Continuous variables use a density; probabilities are areas, computed with the CDF.
- Exponential: waiting time between Poisson events, mean
1/λ, memoryless. - Normal: standardise, then use
Φ(viamath.erforNormalDist). - Gamma: sum of
kexponentials, meank/λ, variancek/λ².
Try it
In the Do tab, write the exponential and normal CDFs and use them for a waiting-time and a measurement question.