How do I take a random sample of rows from a DataFrame in pandas?
Short answer
Use sample with n for a fixed number of rows or frac for a proportion, and set random_state so the sample is reproducible. Use weights for weighted sampling and replace for sampling with replacement.
The short version
Use sample(n=...) for a fixed number of rows, or sample(frac=...) for a proportion of the frame. Always set random_state when you need the same sample again, because without it every run gives different rows. Add weights for weighted sampling and replace=True to allow the same row to be picked more than once.
Fixed number versus proportion
import pandas as pd
df = pd.DataFrame({"x": range(10)})
df.sample(n=3, random_state=42) # exactly 3 rows
df.sample(frac=0.2, random_state=42) # 20 per cent of the rows
n and frac are alternatives; use n when you want a set count and frac when you want a share of whatever size the frame is.
Why random_state matters
Without random_state, sample draws different rows each time it runs, so your analysis is not reproducible and a colleague cannot recreate your result. Setting it to any fixed number makes the draw deterministic.
df.sample(n=3, random_state=42) # same three rows every run
Use this whenever the sample feeds into something you need to repeat, such as a test set or a documented analysis.
Sampling with replacement
By default each row can be chosen at most once, so n cannot exceed the number of rows. To allow repeats, for example when bootstrapping, set replace=True.
df.sample(n=100, replace=True, random_state=0) # rows may repeat
This is the basis of bootstrap resampling, where you deliberately draw a same-sized sample with replacement many times.
Weighted sampling
Pass a column of weights to make some rows more likely to be picked, which is useful when you want a sample that reflects a size or importance.
df.sample(n=3, weights="x", random_state=1)
Rows with larger weights are drawn more often. The weights do not need to sum to one; pandas normalises them.
A common mistake: sampling before sorting
If you sample and then sort, the sample is still random, which is fine. But if you take "the first n rows" of an unsorted or ordered frame thinking it is random, it is not. head(n) gives a systematic slice, not a random one. Use sample whenever you actually need randomness, and head only when you genuinely want the first rows in current order.
Sampling groups evenly
To take the same number from each group rather than from the whole frame, sample within a groupby.
df.groupby("city", group_keys=False).apply(
lambda g: g.sample(n=2, random_state=0), include_groups=False
)
This draws two rows per city, which a plain sample on the whole frame would not guarantee.