svy: Python Package for Complex Survey Design and Analysis
Design-based inference for stratified, cluster, and multi-stage surveys
Documentation
Survey Analysis
Python
Statistics
Professional Python toolkit for designing complex surveys, calculating sample sizes, weighting survey data, and performing statistical analysis with stratified, cluster, and multi-stage sampling designs.
Author
Mamadou S. Diallo, Ph.D.
Published
January 18, 2026
Modified
August 15, 2026
Keywords
complex survey analysis Python, survey design Python package, stratified sampling Python, cluster sampling analysis, PPS sampling Python, survey weighting calibration, variance estimation surveys, design-based inference, Taylor linearization Python, survey bootstrap replication, multi-stage sampling design, probability sampling Python, survey statistics Python, American Community Survey (ACS), Current Population Survey (CPS), National Health and Nutrition Examination Survey, National Health Interview Survey (NHIS), Behavioral Risk Factor Surveillance System (BRFSS), Demographic and Health Survey (DHS), Multiple Indicator Cluster Survey (MICS), European Social Survey (ESS), official statistics, opinion polling Python, R survey package Python alternative, svydesign Python, survey sampling Python, weighted survey estimation Python
What is svy?
svy is a Python package for the design and analysis of complex survey data. When surveys use stratification, clustering, or unequal probability selection, standard software produces incorrect standard errors. svy accounts for the actual sampling design to provide correct design-based estimates (means, totals, proportions, regression models, and more).
svy is designed for modern survey research workflows; it provides good performance, reproducible runs, and convenient pipelines (chains of processing and analysis actions).
Install svy[report] (rather than plain svy) for rich, pretty-printed output.
Quick Start
The examples below run against a small example survey bundled with svy — a subset of a synthetic World Bank household survey. It loads offline, so you can copy‑paste and run everything without any download or setup. See Example Datasets for the full data and how to use your own.
import svy# Load a bundled example survey (runs offline)sample_df = svy.datasets.load("hld_sample_wb_2023", source="bundled")# Describe the complex sampling designdesign = svy.Design( stratum=("geo1", "urbrur"), # stratification psu="ea", # primary sampling units (clusters) wgt="hhweight", # survey weights)sample = svy.Sample(data=sample_df, design=design)print(sample)
╭────────────── Sample ───────────────╮│Survey Data││ Rows : 825 ││ Columns : 19 ││ Strata : 7 ││ PSUs : 33 ││││Survey Design││ Row index svy_row_index ││ Stratum (geo1, urbrur) ││ PSU ea ││ SSU None ││ Weight hhweight ││ With replacement False ││ Prob None ││ Hit None ││ MOS None ││ Population size None ││ Replicate weights None │╰─────────────────────────────────────╯
# Population mean of per-capita expenditure, with a design-based standard errorestimate = sample.estimation.mean("pc_exp")print(estimate)
╭───────────────── Estimate: MEAN (TAYLOR) ──────────────────╮│││ est se lci uci cv (%)││ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ││ 3,810.0716 216.5374 3,364.9725 4,255.1706 5.68 │││╰────────────────────────────────────────────────────────────╯
# Every result exports to a polars DataFrame for further processing# (to_polars() is available on most svy result objects)estimate.to_polars()
shape: (1, 6)
est
se
lci
uci
cv
df
f64
f64
f64
f64
f64
i64
3810.071566
216.537414
3364.972537
4255.170595
0.056833
26
The estimate carries the correct design-based standard error, 95% confidence interval, and coefficient of variation. The same design flows into regression:
# Regression that accounts for the sampling designmodel = sample.glm.fit( y="pc_exp", x=["hhsize", svy.Cat("urbrur")], family="gaussian",)print(model)
svy is the core library, but it’s part of a larger ecosystem of companion packages. Each of these standalone libraries extends the core survey library into a specialized area:
Reading your own data is built into core svy — svy.io.read_csv for CSV files, plus bundled example surveys via svy.datasets.load. The standalone svy-io package adds support for proprietary formats such as SPSS, Stata, and SAS.
Frequently Asked Questions
Is svy a Python alternative to R’s survey package?
Yes. svy is designed to provide equivalent design-based inference to R’s survey package with a Pythonic API. Results have been validated to be numerically identical. See the validation study.
Can I use svy to analyze NHANES, DHS, or BRFSS data?
Yes. svy is built for exactly these surveys. It supports the complex stratified cluster designs used by NHANES, DHS, BRFSS, and similar large-scale public health and demographic surveys.
Does svy support replicate weights?
Yes. svy supports Bootstrap, Balanced Repeated Replication (BRR), Jackknife, and Successive Difference Replication (SDR) replicate weight methods for variance estimation. See the replicate weights tutorial.
What is design-based inference and why does it matter?
Design-based inference accounts for how the sample was drawn (stratification, clustering, unequal probabilities) when calculating standard errors. Ignoring the design typically underestimates standard errors, producing falsely narrow confidence intervals and incorrect hypothesis tests. This can lead to poor decisions.
Is svy production-ready?
Core functionality for survey design, weighting, and variance estimation is stable and production-ready. The API continues to mature. See the development status note below.
How does svy differ from samplics?
svy supersedes samplics, an earlier library by the same author. svy provides a unified Sample object, expanded methodology (GLMs, SAE, data I/O), and active long-term support. samplics is archived.
Development Status
svy is under active development. Core survey design, weighting, and variance estimation are stable and production-ready. APIs and documentation continue to mature.