Chapter 11: Exponential Distribution
1. What is the exponential distribution really?
The exponential distribution describes the time between successive independent events in a Poisson process.
In other words:
If events occur continuously and independently at a constant average rate, then the waiting time until the next event follows an exponential distribution.
This is one of the most important distributions in reliability, queueing, survival analysis, telecommunications, finance (time between trades), and natural phenomena.
Key intuition (memorize this sentence):
The exponential distribution is memoryless — the probability that you have to wait another t minutes for the next event is the same no matter how long you have already waited.
This memoryless property is very unusual and only shared by the exponential (continuous) and geometric (discrete) distributions.
2. The two most important parameters
There are two common ways to parameterize it — both are used in practice:
| Parameterization | Parameter name | Meaning | Typical notation |
|---|---|---|---|
| Rate parameterization | λ (lambda) | average rate of events per unit time | λ > 0 |
| Scale parameterization | β (beta) | average waiting time between events | β = 1/λ |
Relationship: β = 1/λ λ = 1/β
Mean (expected waiting time) = β = 1/λ Variance = β² = 1/λ² Standard deviation = β = 1/λ
3. Generating exponential random numbers in NumPy
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# Using scale parameter (β = mean waiting time) # Example: average 5 minutes between customer arrivals waiting_times = np.random.exponential(scale=5, size=50000) print("First 10 waiting times (minutes):", waiting_times[:10].round(2)) print("Average waiting time:", waiting_times.mean().round(2)) print("Theoretical mean:", 5) print("Standard deviation:", waiting_times.std().round(2)) print("Theoretical std:", 5) |
Alternative (using rate λ):
|
0 1 2 3 4 5 6 7 |
lambda_rate = 0.2 # 0.2 customers per minute → mean = 5 minutes waiting_times_rate = np.random.exponential(scale=1/lambda_rate, size=50000) |
4. Visualizing the exponential distribution (very important)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5.5)) # Different mean waiting times for mean_time in [2, 5, 12, 30]: data = np.random.exponential(scale=mean_time, size=60000) sns.kdeplot(data, label=f"mean = {mean_time}", linewidth=2.3, alpha=0.85) ax1.set_title("Density – Exponential with different means", fontsize=13) ax1.set_xlabel("Waiting time", fontsize=11) ax1.set_ylabel("Density", fontsize=11) ax1.set_xlim(0, 80) ax1.legend(title="Mean waiting time β") # Log scale to show tail behavior x = np.linspace(0.01, 80, 1000) for mean in [2, 5, 12, 30]: ax2.semilogy(x, stats.expon.pdf(x, scale=mean), lw=2.2, label=f"mean = {mean}") ax2.set_title("Log-scale density – heavy right tail", fontsize=13) ax2.set_xlabel("Waiting time (log view)", fontsize=11) ax2.set_ylabel("Density (log scale)", fontsize=11) ax2.legend(title="Mean waiting time β") plt.tight_layout() plt.show() |
What you should always notice:
- Always right-skewed — long tail to the right
- Never negative values
- Starts at maximum density at x=0
- Larger mean → flatter and more stretched out
- On log scale → perfectly straight line downward (unique property of exponential)
5. The memoryless property – the most famous & important feature
Mathematical statement:
P(T > t + s | T > s) = P(T > t)
Translation:
The probability that you still have to wait more than t minutes is the same whether you have already waited s minutes or not.
Real-life interpretation:
- If a machine has already run for 1000 hours without breaking, the probability it breaks in the next hour is the same as if it was brand new.
- If no customer arrived in the last 30 minutes, the expected time until the next customer is still the same as always.
Quick code demonstration
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
beta = 8 # mean waiting time = 8 minutes # Probability of waiting > 15 minutes (from start) p_from_start = np.mean(np.random.exponential(beta, 100000) > 15) # Probability of waiting > 15 more minutes after already waiting 20 minutes # (we simulate by adding 20 to already long waits) long_waits = np.random.exponential(beta, 100000) p_from_20 = np.mean(long_waits[long_waits > 20] - 20 > 15) print(f"P(wait > 15 min from start) ≈ {p_from_start:.4f}") print(f"P(wait > 15 more min after 20 min) ≈ {p_from_20:.4f}") |
Both numbers should be very close → memoryless.
6. Real-world examples you will actually meet
| Domain | Typical use of exponential distribution |
|---|---|
| Reliability engineering | Time to failure of components (assuming constant hazard rate) |
| Queueing theory | Time between customer arrivals (when arrival is Poisson) |
| Survival analysis | Time to event (death, churn, failure, recovery…) |
| Telecommunications | Time between packet arrivals / call arrivals |
| Finance | Time between trades or price jumps (in some models) |
| Natural phenomena | Time between earthquakes, lightning strikes, neuron firings |
| Service systems | Service time / processing time (if memoryless) |
7. Realistic code patterns you will use
Pattern 1 – Simulate time between events
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
# Average 3.5 customers per minute → mean inter-arrival = 1/3.5 ≈ 0.286 min inter_arrivals = np.random.exponential(scale=1/3.5, size=10000) arrival_times = np.cumsum(inter_arrivals) print("Time of first 8 arrivals (minutes):", arrival_times[:8].round(3)) print("Average inter-arrival time:", inter_arrivals.mean().round(4)) |
Pattern 2 – Time to failure simulation
|
0 1 2 3 4 5 6 7 8 9 10 |
# Component with mean lifetime 1200 hours lifetimes = np.random.exponential(scale=1200, size=5000) print("Probability of failing within first 500 hours:", np.mean(lifetimes <= 500).round(4)) print("Median lifetime:", np.median(lifetimes).round(1)) |
Pattern 3 – Exponential CDF (probability of waiting less than t)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
t_values = np.linspace(0, 40, 1000) beta = 6 prob_less_than_t = 1 - np.exp(-t_values / beta) plt.plot(t_values, prob_less_than_t, lw=2.8, color="teal") plt.title(f"CDF – Exponential (mean waiting time = {beta} min)") plt.xlabel("Waiting time (min)") plt.ylabel("P(wait ≤ t)") plt.axvline(beta, color="darkred", ls="--", label=f"mean = {beta}") plt.legend() plt.show() |
Summary – Exponential Distribution Quick Reference
| Property | Value / Formula |
|---|---|
| Shape | Right-skewed, decays exponentially |
| Defined by | rate λ or scale β = 1/λ |
| Mean | β = 1/λ |
| Variance | β² = 1/λ² |
| Standard deviation | β = 1/λ |
| Memoryless property | Yes — unique among continuous distributions |
| λ exp(-λx) for x ≥ 0 | |
| CDF | 1 − exp(-λx) for x ≥ 0 |
| NumPy function | np.random.exponential(scale=β, size=…) |
| Most common use cases | time between Poisson events, time to failure, inter-arrival times, service times |
Final teacher messages
- Whenever you are modeling “time until the next event” and the events follow a Poisson process → use exponential.
- Exponential is the only continuous memoryless distribution — very powerful and very unusual property.
- Exponential + Poisson are twins:
- Poisson counts events in fixed interval
- Exponential measures time between events
Would you like to continue with any of these next?
- Deep dive into memoryless property with more examples
- Exponential vs Weibull (when hazard rate is not constant)
- Relationship between exponential and gamma distribution
- Realistic mini-project: simulate a queue / call center
- How to estimate λ from real data
Just tell me what you want to explore next! 😊
