Q&A library Python

How do I take a random sample of rows from a DataFrame in pandas?

Python Intermediate randomreproducibilitysample

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.

Need this solved on your own data?

The library is free and always will be. When the problem is bigger than an answer, we take on the work.

Start a project