Quick answer: NumPy’s Poisson generator produces non-negative count samples for a rate lambda. Lambda is both the expected mean and theoretical variance; use a dedicated Generator for reproducibility, pass size for shape, and validate that the rate matches the interval being modeled.

NumPy random Poisson sampling generates integer counts from a Poisson distribution. Use it when you want to model how many times an independent event happens in a fixed interval, such as support tickets per hour, defects per batch, website visits per minute, or particle counts in an experiment. The key parameter is lam, the expected number of events in the interval.
For new code, prefer np.random.default_rng() and Generator.poisson(). The older np.random.poisson() function still exists, but NumPy’s current random API is built around random generator objects. A generator makes reproducibility clearer and keeps random state local to your code.
Basic NumPy random Poisson example
The simplest call passes a lam value and a size. The result is an array of non-negative integers. In the example below, lam=3.5 means the average event count is expected to be around 3.5 per interval.
import numpy as np
rng = np.random.default_rng(42)
samples = rng.poisson(lam=3.5, size=10)
print(samples)The actual values will vary unless you pass a fixed seed to default_rng(). Use a seed for examples, tests, and tutorials. Avoid hard-coding one in production simulations unless repeatability is required.
What lam means
The lam parameter is the expected count for the interval you are modeling. If a help desk receives an average of 4 tickets per hour, lam=4 models hourly ticket counts. If your interval changes from one hour to one day, the value of lam must change too. The parameter is not a probability; it is an expected count.
Poisson samples are always whole counts: 0, 1, 2, and so on. If your data can be negative, continuous, or limited to a fixed maximum number of trials, a different distribution is probably more appropriate.
Generate arrays with size
The size argument controls the shape of the output. Pass an integer for a one-dimensional sample, or pass a tuple for a multidimensional array. This is useful when you need simulated counts for rows, columns, days, users, or experiments.
import numpy as np
rng = np.random.default_rng(7)
counts = rng.poisson(lam=2.0, size=(3, 4))
print(counts)
print(counts.shape)If you need evenly spaced values rather than random counts, use tools such as NumPy arange. Random sampling and range creation solve different problems.

Check the sample mean
A large Poisson sample should have a mean close to lam. It will not match exactly because the sample is random. This quick check is useful when you want to confirm that the simulation parameters make sense.
import numpy as np
rng = np.random.default_rng(123)
lam = 5
samples = rng.poisson(lam=lam, size=10000)
print(samples.mean())
print(samples.var())For a Poisson distribution, the mean and variance are both equal to lam in theory. PythonPool’s NumPy mean guide covers the averaging function if you need more detail on axes, dtype, or array shape.
Plot a Poisson histogram
A histogram makes it easier to see where most generated counts land. Because Poisson output is discrete, use integer-centered bins when plotting. The NumPy histogram guide is useful if you want to compute bin counts directly.
import numpy as np
import matplotlib.pyplot as plt
rng = np.random.default_rng(42)
samples = rng.poisson(lam=3.5, size=1000)
bins = np.arange(samples.min(), samples.max() + 2) - 0.5
fig, ax = plt.subplots()
ax.hist(samples, bins=bins, edgecolor="black")
ax.set_xlabel("event count")
ax.set_ylabel("frequency")
ax.set_title("Poisson samples, lam=3.5")
plt.show()
Compare different lam values
As lam increases, the distribution shifts right and spreads out. This is a useful way to explain expected event counts to readers or stakeholders. If your data is continuous and bell-shaped, compare this with NumPy random normal. If every value inside a range should be similarly likely, see NumPy random uniform.
import numpy as np
rng = np.random.default_rng(5)
for lam in [1, 3, 8]:
samples = rng.poisson(lam=lam, size=1000)
print(lam, samples.mean(), samples.max())Poisson noise for images
Poisson noise appears in image and sensor data when pixel values represent counts or intensity measurements. A simple simulation scales the image, samples from a Poisson distribution, and scales the result back. Use this only when the model matches the data; do not add Poisson noise to every image by default.
import numpy as np
from matplotlib import image as mpimg
image = mpimg.imread("input.png")
scaled = np.clip(image, 0, 1) * 255
rng = np.random.default_rng(42)
noisy = rng.poisson(scaled) / 255
noisy = np.clip(noisy, 0, 1)If you load images with Matplotlib, the Matplotlib imread guide explains common return shapes and dtype behavior.
Common mistakes
- Using lambda as a variable name: Python reserves
lambda, so NumPy useslam. - Expecting decimals: Poisson samples are integer counts.
- Confusing lam with probability:
lamis an expected count, not a probability from 0 to 1. - Using one global random state everywhere: prefer a local generator from
default_rng(). - Choosing Poisson for every random problem: use normal, uniform, binomial, or exponential distributions when their assumptions match better.
For boolean filtering after generating samples, PythonPool’s NumPy logical_and guide shows how to combine array conditions cleanly.

Official NumPy references
- numpy.random.Generator.poisson
- numpy.random.poisson legacy function
- NumPy random Generator
- Generator.normal
- Generator.binomial
- Generator.exponential
Interpret Lambda
Lambda is the expected number of events in the fixed interval represented by one sample. Changing the interval or exposure changes lambda, so do not treat it as a universal property of the event type.
Use A Dedicated Generator
A seeded NumPy random Generator makes experiments reproducible without relying on global random state. Keep the seed and generator construction in the experiment configuration, not hidden inside a helper.

Choose The Output Shape
A scalar size produces one sample, an integer produces a one-dimensional array, and a tuple produces a multidimensional array. Confirm shape before combining samples with other arrays.
Check Empirical Behavior
For a sufficiently large sample, the mean and variance should be near lambda, but random variation is expected. Do not reject a valid simulation because a small sample does not match the theoretical moments exactly.
Handle Invalid Rates
Lambda must be non-negative and finite for a standard Poisson model. Validate the rate before sampling and document what zero means for the application rather than silently accepting malformed data.
NumPy’s Generator.poisson() reference defines lambda and size. Related references include variance, array shapes, and reproducible tests.
For related NumPy modeling, compare variance, array shapes, and reproducible tests when validating Poisson samples.
Frequently Asked Questions
What does NumPy random poisson generate?
It generates samples from a Poisson distribution representing counts with a non-negative lambda rate.
What does lambda mean in a Poisson distribution?
Lambda is the expected count for the interval and, theoretically, the variance as well.
How do I make Poisson samples reproducible?
Create a NumPy random Generator with a fixed seed and call its poisson method.
What shape does the output have?
The size argument controls the output shape; omit it for a scalar sample or pass an integer or tuple for arrays.