cdc-nhanes-dl
Takes a local snapshot of the entire public NHANES dataset — every table, every survey cycle — and leaves you with Parquet files you can open in pandas.
This is not a query API. It mirrors what CDC publishes to your disk in one shot: no API key, no auth, no rate limits to negotiate. Run it once to get the dataset, re-run it later to pick up new cycles. Every step skips work already on disk, so an interrupted run resumes where it stopped.
Expect roughly 6 GB and 15–40 minutes on a decent connection for the full set.
Install
pip install git+https://github.com/ink-waffle/cdc-nhanes-dl
Get the data
cdc-nhanes-dl
That writes to output/nhanes/ relative to your current directory. The part you'll actually use is output/nhanes/nhanes_tables/:
import pandas as pd
bmx = pd.read_parquet("output/nhanes/nhanes_tables/BMX — Body Measures.parquet")
bmx[["SEQN", "CYCLE", "BMXWT — Weight (kg)", "BMXBMI — Body Mass Index (kg/m**2)"]].head()
One file per table, with all cycles stacked into it. SEQN is the respondent ID (join key across tables), CYCLE tells you which survey wave a row came from.
Don't need everything? Narrow it:
cdc-nhanes-dl --tables BMX,DEMO,GHB # just these tables, all cycles
cdc-nhanes-dl --cycles 2017-2018,2021-2023 # just these cycles, all tables
cdc-nhanes-dl -o ~/data/nhanes -w 16 # elsewhere, more parallelism
Column names
Raw NHANES variable codes are unreadable, so columns are renamed to CODE — Label using the labels embedded in CDC's SAS files:
BMXWT — Weight (kg)
LBXGH — Glycohemoglobin (%)
RIDAGEYR — Age in years at screening
The bare code stays available in Parquet metadata if you need to map back — per column under the nhanes_code field key, or for the whole table as a JSON map under nhanes_columns.
Typed schemas
The final step generates pandera models under output/nhanes/types/, one module per component, so you get autocomplete over those long column names instead of typing them by hand:
from output.nhanes.types.examination.types import BmxSchema
BmxSchema.validate(bmx)
bmx[BmxSchema.bmxbmi] # -> "BMXBMI — Body Mass Index (kg/m**2)"
Requires pip install pandera. Pass --import-prefix to match wherever the generated package ends up on your import path (--import-prefix output.nhanes.types for the layout above).
What it produces
output/nhanes/
├── xpt/<cycle>/ raw SAS transport files, as downloaded
├── parquet/<cycle>/ one-to-one Parquet conversion
├── nhanes_tables/ cycles stacked per table ← use these
├── types/ generated pandera schemas
├── table_categories.json table → component
└── table_descriptions.json table → plain-English name
xpt/ and parquet/ are intermediates; they exist so re-runs don't re-download and so you can go back to the source if a conversion looks wrong. Delete them once you have nhanes_tables/ and you save about 4 GB.
Pipeline steps
| Step | Does |
|---|---|
download |
scrapes CDC's table manifest, fetches every XPT |
convert |
XPT → Parquet, preserving SAS column labels |
metadata |
scrapes component + description for every table |
combine |
strips cycle suffixes, stacks rows, renames columns |
types |
writes pandera schemas |
Run one on its own with --only, or exclude one with --skip-<step>:
cdc-nhanes-dl --only download
cdc-nhanes-dl --skip-types
Individual steps are also importable and directly runnable:
python -m cdc_nhanes_dl.download --cycles 2017-2018
python -m cdc_nhanes_dl.combine --tables BMX
Caveats
- Tables with no
SEQNcolumn — format lookups, pooled-sample files — are skipped bycombine, since they have no respondent to join on. They're still inparquet/. - Multi-cycle aggregate releases (
1999-2004,1988-2020, …) are downloaded but excluded from stacking; their rows already appear in the individual cycles. - When a variable is text in one cycle and numeric in another, the stacked column becomes text. Cast it yourself.
- When a label was reworded between cycles, the most recent wording is used for the whole column.
- Limited Access tables are listed in the metadata but their data is not public — CDC gates it behind the RDC, so those downloads fail and are reported as such.
Tests
pip install -e ".[dev]"
pytest # runs the real pipeline over 2 small tables
pytest -m "not network" # offline only
Licence
MIT. The data itself is public domain, published by the US CDC / NCHS.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cdc_nhanes_dl-0.1.0.tar.gz.
File metadata
- Download URL: cdc_nhanes_dl-0.1.0.tar.gz
- Upload date:
- Size: 21.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
114630c3126c32a8d00ec42e3fc48bdacd0f5b1bad14ac26e01c14417565de0d
|
|
| MD5 |
0007db92c832e813e8f544d04df675bf
|
|
| BLAKE2b-256 |
d5c4acb18715dc3028956ac0b07519db3008563d6b07275615a4c48cdf3b15bf
|
Provenance
The following attestation bundles were made for cdc_nhanes_dl-0.1.0.tar.gz:
Publisher:
release.yml on ink-waffle/cdc-nhanes-dl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cdc_nhanes_dl-0.1.0.tar.gz -
Subject digest:
114630c3126c32a8d00ec42e3fc48bdacd0f5b1bad14ac26e01c14417565de0d - Sigstore transparency entry: 2306858926
- Sigstore integration time:
-
Permalink:
ink-waffle/cdc-nhanes-dl@3a24460f170234cb7b94e562a575656b4745abe7 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ink-waffle
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3a24460f170234cb7b94e562a575656b4745abe7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cdc_nhanes_dl-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cdc_nhanes_dl-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d09513b074dcc5ff5d7e6708d9e228c541add7f777e343494c79b5b964d9885b
|
|
| MD5 |
6ac080558939f930ebde7589c8ae4391
|
|
| BLAKE2b-256 |
643b75477df3b54f5b994423a8d4997a5159e51bd6068219be49ed2ae3278816
|
Provenance
The following attestation bundles were made for cdc_nhanes_dl-0.1.0-py3-none-any.whl:
Publisher:
release.yml on ink-waffle/cdc-nhanes-dl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cdc_nhanes_dl-0.1.0-py3-none-any.whl -
Subject digest:
d09513b074dcc5ff5d7e6708d9e228c541add7f777e343494c79b5b964d9885b - Sigstore transparency entry: 2306858938
- Sigstore integration time:
-
Permalink:
ink-waffle/cdc-nhanes-dl@3a24460f170234cb7b94e562a575656b4745abe7 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ink-waffle
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3a24460f170234cb7b94e562a575656b4745abe7 -
Trigger Event:
push
-
Statement type: