Lesson 10 · Probability and Statistics in python
Understanding Bernoulli, Binomial, and Poisson Discrete Probability Distributions
In this lesson, we will learn about three popular types: Bernoulli distribution Binomial distribution Poisson distribution These are core building blocks in…
- CourseProbability and Statistics in python
- Lesson10 of 35
- Video9 min
- FormatJupyter notebook · 13 code cells
What you'll learn
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbWelcome to Discrete Distributions in Probability!#
In this lesson, we will learn about three popular types:
- Bernoulli distribution
- Binomial distribution
- Poisson distribution
These are core building blocks in probability and statistics.
Let us jump in together!
# Importing the libraries we need
import warnings; warnings.filterwarnings("ignore")
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Data setup
df_titanic = sns.load_dataset("titanic")
print("Titanic shape:", df_titanic.shape)
print(df_titanic.head())
What is a Discrete Distribution?#
A discrete distribution is a way to model situations where outcomes can only take certain values.
For example: flipping a coin (only heads or tails), or counting how many emails you receive per hour.
Let us start with the Bernoulli distribution.
# Bernoulli Distribution: Simulating one coin flip
p = 0.5 # Probability of heads
flip = np.random.binomial(1, p)
print(f"Coin flip result (1=heads, 0=tails): {flip}")
# Simulate 20 coin flips and plot the results
flips = np.random.binomial(1, p, 20)
print("Coin flip outcomes:", flips)
plt.figure(figsize=(5,2))
sns.histplot(flips, bins=2, discrete=True)
plt.xticks([0,1], ['Tails', 'Heads'])
plt.title('Coin Flip Outcomes: 20 Bernoulli Trials')
plt.ylabel('Count')
plt.show()
Binomial Distribution#
The binomial distribution models the number of successes you get in a set number of independent trials.
For example: How many heads will you get if you flip a coin 10 times?
# Simulate 10 coin flips and count heads (k successes in n trials)
n = 10 # number of flips
p = 0.5 # probability of heads
heads_count = np.random.binomial(n, p)
print(f"Number of heads in 10 flips: {heads_count}")
# What does the binomial distribution look like?
results = [np.random.binomial(n, p) for _ in range(1000)]
plt.figure(figsize=(6,3))
sns.histplot(results, bins=n+1, discrete=True)
plt.xlabel('Number of Heads in 10 Flips')
plt.ylabel('Frequency')
plt.title('Distribution of Heads (10 flips, 1000 simulations)')
plt.show()
# Estimate probability: How often do we get at least 8 heads in 10 flips?
results = np.random.binomial(n, p, 10000)
prob_8_or_more = np.mean(results >= 8)
print(f"Probability of getting 8 or more heads in 10 flips: {prob_8_or_more:.3f}")
Can you spot binomial distributions outside of coins?#
Any situation with repeated yes or no events can be modeled with binomial distributions.
What about the number of passengers who survived on the Titanic?
# Apply binomial idea to Titanic survivor data
n_total = df_titanic["survived"].dropna().shape[0]
p_survive = df_titanic["survived"].mean()
simulated_survivors = np.random.binomial(n_total, p_survive)
print(f"Out of {n_total} passengers, about {simulated_survivors} would survive with this probability.")
Poisson Distribution#
The Poisson distribution models how many times an event happens in a fixed interval, when the events are rare and independent.
For example: How many emails do you get in a day?
# Simulate how many emails you get in a day (lambda is average rate)
lam = 5 # average 5 emails per day
emails_per_day = np.random.poisson(lam)
print(f"You got {emails_per_day} emails today.")
# Simulate and plot your email counts for 30 days
emails = np.random.poisson(lam, 30)
plt.figure(figsize=(6,3))
plt.bar(range(1, 31), emails, color='skyblue')
plt.xlabel('Day')
plt.ylabel('Emails Received')
plt.title('Simulated Daily Email Counts for One Month')
plt.show()
# What most likely number of emails can you get in a day?
emails_samples = np.random.poisson(lam, 10000)
values, counts = np.unique(emails_samples, return_counts=True)
most_likely = values[np.argmax(counts)]
print(f"The most likely number of emails in a day is: {most_likely}")
# Input: Your estimated average emails per day
user_lambda = int(input("Estimate how many emails you get per day, on average: "))
sim = np.random.poisson(user_lambda, 14)
print(f"Emails you might get over 2 weeks: {sim}")
Summary Table: When to use which discrete distribution?#
| Situation | Typical Model |
|---|---|
| 1 event, two outcomes | Bernoulli |
| Many tries, two outcomes | Binomial |
| Rare events per interval | Poisson |
# Mini-project: Model rare phone calls per hour with Poisson
lam = 2 # average phone calls per hour
n_hours = 100
calls = np.random.poisson(lam, n_hours)
plt.figure(figsize=(6,3))
sns.histplot(calls, bins=range(0, max(calls)+2), discrete=True, color='coral')
plt.xlabel('Calls in an Hour')
plt.ylabel('Number of Hours')
plt.title('Simulated Phone Calls over 100 Hours')
plt.show()
Self-check: Try it yourself!#
- Simulate 10,000 days and plot how many days have exactly 3 phone calls.
- Try it with different average rates (lambda) and see patterns.
Keep exploring, and take notes on what you notice!
Recap & Next Steps#
Great job learning about Bernoulli, Binomial, and Poisson distributions!
Next, you can dive deeper into real dataset analysis, or continue practicing with new problems.
Try adapting the code for your own experiments.
If you found this helpful, Like & Subscribe!#
Share your results and questions in the comments, and check out our next Python stats video soon.
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



