Skip to main content
v2026.11,858 entries · CC-BY 4.0
LAC HealthMedical & Research SuppliesReagents, PPE & instruments — chain-of-custody documented.Fast, traceable sourcing built for regulated research environments, from bench consumables to instrumentation.Shop lac.us CodeCASRAIlac.us

Random Sampling in Python: random.sample, NumPy and pandas

Draw a reproducible random sample in Python with random.sample, NumPy Generator.choice or pandas DataFrame.sample, with seeds, errors and a method table.

Written and maintained by CASRAI Editorial Board

Last updated

Researchers searching for this usually have a list of participants, records or samples and need to draw a random subset reproducibly, then report how they did it. Python offers four standard routes: random.sample(), random.choices(), NumPy’s Generator.choice() and pandas’ DataFrame.sample(). The short answer: use DataFrame.sample() when your sampling frame is a table, Generator.choice() when it is an array or a list of IDs, and the standard-library random.sample() for a plain list. Details below follow each library’s official documentation (read 2026-11-08).

What random sampling in Python is used for in research

A simple random sample gives every unit in the sampling frame the same chance of selection. In practice researchers use it to pick participants from a registry, to select records for a manual audit or coding check, to build a validation subset, or to draw a pilot sample from a larger dataset. Two choices matter before any code runs: whether units may be selected more than once (sampling with replacement) and whether selection probabilities are equal or weighted. Python’s functions differ on exactly these points.

Install or access

The random module ships with Python itself (docs.python.org). NumPy and pandas are separate packages from their official projects; install them with pip install numpy pandas and check the installed versions with numpy.__version__ and pandas.__version__, which you will want to record for your methods section.

Choosing the right function

Function Replacement Weights Seed / reproducibility Input
random.sample(population, k, *, counts=None) Without: returns k unique elements None (the counts argument, added in 3.9, repeats elements instead) random.seed(a) on the module A sequence (since Python 3.11 a set is no longer converted automatically)
random.choices(population, weights=None, *, cum_weights=None, k=1) With weights or cum_weights, same length as the population random.seed(a) A sequence
Generator.choice(a, size=None, replace=True, p=None, axis=0, shuffle=True) Either, set by replace p, must sum to 1 Seed passed to np.random.default_rng() Array-like, or an integer n meaning arange(n)
DataFrame.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None, ignore_index=False) Either, set by replace weights: a column name or an aligned Series random_state (int, BitGenerator, RandomState or Generator) A DataFrame or Series

Sources: Python random docs, NumPy Generator.choice docs and pandas DataFrame.sample docs (all read 2026-11-08). The default of replace differs: Generator.choice defaults to True, while random.sample and DataFrame.sample sample without replacement by default.

Step-by-step: draw a reproducible simple random sample

1. Sampling from a table with pandas

  1. Load your sampling frame into a DataFrame, one row per eligible unit, with duplicates and ineligible units already removed. Sampling cannot correct a flawed frame.
  2. Call sample with either a count or a fraction, and a fixed seed:
    sample_df = df.sample(n=100, random_state=42)

    or, for a proportion of the rows:

    sample_df = df.sample(frac=0.10, random_state=42)

    n and frac are mutually exclusive; if neither is given, n=1.

  3. Set replace=True only if you want sampling with replacement. It is required when frac is greater than 1.
  4. Optionally pass ignore_index=True to relabel the result 0 to n-1.

2. Sampling IDs or an array with NumPy

  1. Create a generator with a recorded seed: rng = np.random.default_rng(12345).
  2. Draw without replacement: chosen = rng.choice(ids, size=100, replace=False). For a 2-D array, axis=0 (the default) selects rows.

According to the NumPy documentation, rng.choice(5, 3, replace=False) is equivalent to rng.permutation(np.arange(5))[:3], and supplying p uses a slower sampler.

3. Sampling a plain list with the standard library

  1. import random, then optionally random.seed(2026). An integer seed is used directly; with None, Python uses system time or operating-system randomness, so results will differ on each run.
  2. subset = random.sample(ids, k=100) returns a list of 100 unique elements.
  3. For sampling with replacement or unequal weights use random.choices(ids, weights=w, k=100).

4. Record what you did

For the methods section, report the sampling frame and its size, the function used, the sample size, whether sampling was with or without replacement, the seed, and the Python, NumPy and pandas versions. A seed alone does not reproduce a draw across libraries, so name the exact function. This supports reproducibility of the selection step.

Output and how to read it

Each function returns the selected elements: random.sample and random.choices return a list, Generator.choice an array, and DataFrame.sample a DataFrame or Series whose index labels are those of the original rows (unless ignore_index=True). In the pandas documentation example, df["num_legs"].sample(n=3, random_state=1) returns three index-labelled rows (fish, spider, falcon): the labels show which original records were drawn, so keep them as your record of selection. Row order in the output is random too; sort by index if you need the original order.

Weighted draws: pandas normalises weights that do not sum to 1, treats NaN weights as zero and does not allow infinite weights. A selected sample is one realisation; its estimates differ from the population value by sampling error, which a larger n reduces.

Troubleshooting

Symptom Cause (per official docs) Fix
ValueError from random.sample k larger than the population Reduce k, or sample with replacement using random.choices
Error passing a set to random.sample (Python 3.11+) Population must be a sequence; sets are no longer converted Convert first, for example sorted(my_set)
TypeError from random.choices Both weights and cum_weights were given Supply only one
ValueError from random.choices All weights are zero (3.9+) Give at least one non-zero weight
IndexError from random.choices Empty population Check the filter that built the list
ValueError from Generator.choice replace=False with size larger than the population Reduce size or set replace=True
Error from DataFrame.sample with frac above 1 replace must be True when frac is greater than 1 Set replace=True or use frac of 1 or less
Error combining n and frac The two are mutually exclusive Pass one
Weighted pandas draw rejected With replace=False, n*max(weights)/sum(weights) above 1 is not allowed Lower n or use replace=True
Different sample each run No seed set (seed(None), no random_state) Set and record a seed

Do not use the random module for security purposes; the Python documentation directs security uses to the secrets module. Sampling within groups (stratified draws) is available through pandas’ DataFrameGroupBy.sample, listed under “See also” in the DataFrame.sample documentation; see our stratified sampling guide for the design side.

Alternatives within Python

All four options below are part of Python or the NumPy and pandas packages. Pick by input type:

If your data is Use Why (from the docs)
A DataFrame DataFrame.sample Keeps index labels, accepts frac, takes weights from a column
A NumPy array or ID vector Generator.choice Seeded generator object; replace and p arguments
A short list, no extra packages random.sample Standard library; unique elements only
Need replacement or weights on a list random.choices Weights or cumulative weights, k draws with replacement

For deeper treatment of NumPy’s function see NumPy random choice; for fixed-interval selection see systematic sampling.

FAQ

How do I take a random sample without replacement in Python?

Use random.sample(population, k), rng.choice(a, size, replace=False) with a NumPy generator, or df.sample(n=...) in pandas, which does not replace by default.

How do I make a random sample reproducible?

Set a seed: random.seed(n) for the standard library, np.random.default_rng(n) for NumPy, or random_state=n in pandas. Record the seed and library versions.

What is the difference between random.sample and random.choices?

random.sample returns unique elements (without replacement); random.choices draws with replacement and accepts weights.

Can I sample a percentage of rows in pandas?

Yes: df.sample(frac=0.2) returns 20% of rows. Do not combine frac with n.

Is Python’s random module suitable for cryptography?

No. The documentation says to use secrets for security purposes.

Sources

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Random Sampling in Python: random.sample, NumPy and pandas

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →