Datasets (Bundled and Remote)

Ready-to-use survey datasets for learning and offline work

Tutorials
Datasets
Survey Analysis
Python
Load the example survey datasets bundled with svy and run the tutorials offline, or read your own CSV, Parquet, SPSS, Stata, and SAS files into a Sample.
Author

Mamadou S. Diallo, Ph.D.

Published

July 21, 2026

Modified

July 21, 2026

Keywords

svy example datasets, survey data Python, synthetic survey data, offline survey datasets Python, World Bank synthetic survey data, household survey example data, svy.datasets load, read SPSS file Python, read Stata file Python, read SAS file Python, read parquet survey data Python

svy ships with a handful of datasets so you can learn the library and run every example in these docs without downloading anything. They are small, realistic, and load instantly — offline.

These bundled files are compact subsets of larger synthetic datasets that svy also hosts online. For learning and for reproducible documentation they are ideal; when you need the full data, the same call fetches it (more on this below).

This page covers what’s available, how to load it, and how the pieces fit together.

What’s available

The bundled data is a small, self-consistent synthetic survey (from the World Bank) covering four administrative regions: a sampling frame, the household census of that frame, and a survey sample drawn from it. Call catalog() to list them:

import svy

print(svy.datasets.catalog(source="bundled"))
╭──────────────────────────────────────────── Datasets ─────────────────────────────────────────────╮
 Number of datasets    4                                                                           
 Total size            1.0 MB                                                                      
                                                                                                   
                                                                                                   
  slug                   title                                          rows     cols        size  
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
  ea_frame_wb_2023       WB Synthetic EA Frame 2023 (bundled sub…        133        5        3 KB  
  hld_pop_wb_2023        WB Synthetic Household Census 2023 (bun…     57,867       15     1019 KB  
  hld_sample_wb_2023     WB Synthetic Household Sample 2023 (bun…        825       16       24 KB  
  ind_sample_wb_2023     WB Synthetic Individual Sample 2023 (bu…      3,246       15       29 KB  
                                                                                                   
╰───────────────────────────────────────────────────────────────────────────────────────────────────╯
  • ea_frame_wb_2023 — the enumeration-area (EA) sampling frame.
  • hld_pop_wb_2023 — the household census (the population living in the frame’s EAs).
  • hld_sample_wb_2023 / ind_sample_wb_2023 — the survey sample drawn from that census, at the household and individual level.

The individual census (ind_pop_wb_2023) is not bundled — it’s large and rarely needed offline. It stays available via source="remote"; asking for it as source="bundled" returns a clear error pointing you there.

For the full metadata of any one — its description, design, and size — drill in with .get():

print(svy.datasets.catalog(source="bundled").get("hld_sample_wb_2023"))
╭───────────────────────── Dataset: hld_sample_wb_2023 ─────────────────────────╮
 Title          WB Synthetic Household Sample 2023 (bundled subset)            
 Description    Two-stage (PPS + SRS) household sample with design weights.    
 Rows × Cols    825 × 16                                                       
 Size           24 KB                                                          
 Version        1.0.0                                                          
 Design                                                                        
                stratum = ['geo1', 'urbrur']                                   
                psu = 'ea'                                                     
                wgt = 'hhweight'                                               
 Source         World Bank Microdata Library (catalog 5906)                    
 License        World Bank synthetic microdata terms                           
 Tags           wb, synthetic, household, sample, bundled                      
 Notes          Bundled offline subset derived from the full remote dataset:   
                fewer regions and a curated column set. Load source='remote'   
                for the complete data. The sample is re-drawn from the bundled 
                census, so its weights match the bundled population (not the   
                national one).                                                 
╰───────────────────────────────────────────────────────────────────────────────╯

Loading a dataset

svy.datasets.load returns a Polars DataFrame; svy.datasets.describe returns its metadata — including the sampling design, ready to spread into svy.Design:

data = svy.datasets.load("hld_sample_wb_2023", source="bundled")
info = svy.datasets.describe("hld_sample_wb_2023", source="bundled")

info.design
{'stratum': ['geo1', 'urbrur'], 'psu': 'ea', 'wgt': 'hhweight'}

That means you can go from a slug to a design-based estimate in three lines:

sample = svy.Sample(data, svy.Design(**info.design))
print(sample.estimation.mean("pc_exp"))
╭───────────────── Estimate: MEAN (TAYLOR) ──────────────────╮
                                                            
         est         se          lci          uci   cv (%)  
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  
  3,810.0716   216.5374   3,364.9725   4,255.1706     5.68  
                                                            
╰────────────────────────────────────────────────────────────╯

Choosing a source

Every load / catalog / describe call takes a source= argument:

source= Where the data comes from Internet?
"bundled" The compact subset shipped inside svy Not needed
"remote" The full dataset hosted online Required
"auto" (default) Remote if reachable, otherwise the bundled subset Falls back

To pull the full dataset, ask for it explicitly:

# The full online dataset (requires internet)
full = svy.datasets.load("hld_sample_wb_2023", source="remote")

Set the SVYLAB_OFFLINE=1 environment variable to make "auto" skip the network entirely and always use the bundled data — handy for CI or working on a plane.

Bundled vs. full data

The bundled data is a faithful slice of the full remote data for the selected strata, not a lossy approximation. It differs in three documented ways (each dataset’s notes field spells this out):

  • Fewer regions — 4 of the ~10 administrative regions.
  • A curated column set — ~15 analysis variables, not the full schema.
  • A re-drawn sample — the sample is drawn from the bundled census, so its weights inflate to this population.

Within those bounds, hld_pop is the true population of the frame’s EAs — nothing is subsampled — so weighted sample estimates genuinely match it. The design weights sum exactly to the census count:

census = svy.datasets.load("hld_pop_wb_2023", source="bundled")
hh = svy.datasets.load("hld_sample_wb_2023", source="bundled")

print("Σ weights:", round(hh["hhweight"].sum()), "| census households:", census.height)
Σ weights: 57867 | census households: 57867

For the complete data — all regions and every column — load with source="remote".

How the datasets fit together

The four files share one set of enumeration areas, so they reconcile:

  • ea_frame lists every EA, with its census household count as the PPS measure of size;
  • hld_pop is the household census over exactly those EAs;
  • hld_sample is a two-stage sample (PPS EAs → SRS households) drawn from that census;
  • ind_sample holds the sampled households’ individuals, enriched with the household design columns (geo1, geo2, ea, urbrur) so individual-level estimation needs no manual join.

So the sample’s EAs are a subset of the frame’s, and every sampled household appears in the census:

frame = svy.datasets.load("ea_frame_wb_2023", source="bundled")

print("sampled EAs ⊂ frame EAs:", set(hh["ea"]).issubset(set(frame["ea"])))
print("sampled households ⊂ census:", set(hh["hid"]).issubset(set(census["hid"])))
sampled EAs ⊂ frame EAs: True
sampled households ⊂ census: True

Bringing your own data

The example datasets are just a convenient starting point. To analyze your own survey, read it into a Polars DataFrame with svy.io and build a Sample the same way. svy reads the common survey formats:

Format Reader Backed by
CSV svy.io.read_csv Polars
Parquet svy.io.read_parquet Polars
SPSS (.sav) svy.io.read_spss (alias read_sav) svy-io
Stata (.dta) svy.io.read_stata (alias read_dta) svy-io
SAS (.sas7bdat) svy.io.read_sas svy-io

CSV and Parquet are thin wrappers around Polars (scan_csv / scan_parquet return lazy frames). The proprietary formats — SPSS, Stata, and SAS — are handled by the svy-io engine, which also preserves value and variable labels; use the *_with_labels variants (e.g. read_spss_with_labels) to capture them.

import svy

# Read your file (any of the readers above), then attach the design
data = svy.io.read_spss("my_survey.sav")   # or read_csv / read_stata / read_sas / …

sample = svy.Sample(
    data,
    svy.Design(stratum="stratum", psu="psu", wgt="weight"),
)

Next Steps

Now that you can load data, learn to clean and reshape it.

Keep going?
Continue to Data Wrangling →