Tutorial 3: Multi-Year Comparisons¶
cendat makes it easy to compare data across multiple years.
Goal: Find Colorado incorporated places with very low poverty rates across recent years.
Setup¶
In [1]:
Copied!
import os
from cendat import CenDatHelper
from dotenv import load_dotenv
load_dotenv()
cdh = CenDatHelper(key=os.getenv("CENSUS_API_KEY"))
# Request multiple years at once
cdh.list_products(years=[2020, 2021, 2022, 2023], patterns=r"acs/acs5\)")
cdh.set_products()
import os
from cendat import CenDatHelper
from dotenv import load_dotenv
load_dotenv()
cdh = CenDatHelper(key=os.getenv("CENSUS_API_KEY"))
# Request multiple years at once
cdh.list_products(years=[2020, 2021, 2022, 2023], patterns=r"acs/acs5\)")
cdh.set_products()
✅ API key loaded successfully.
✅ Product set: 'American Community Survey: 5-Year Estimates: Detailed Tables 5-Year (2020/acs/acs5)' (Vintage: [2020]) ✅ Product set: 'American Community Survey: 5-Year Estimates: Detailed Tables 5-Year (2021/acs/acs5)' (Vintage: [2021]) ✅ Product set: 'American Community Survey: 5-Year Estimates: Detailed Tables 5-Year (2022/acs/acs5)' (Vintage: [2022]) ✅ Product set: 'ACS 5-Year Detailed Tables (2023/acs/acs5)' (Vintage: [2023])
Step 2: Select Data¶
In [2]:
Copied!
cdh.set_groups(["B17001"])
cdh.set_geos(["160"]) # Places
cdh.set_groups(["B17001"])
cdh.set_geos(["160"]) # Places
✅ Groups set: B17001
✅ Geographies set: 'place' (requires `within` for: state)
Step 3: Get Data¶
In [3]:
Copied!
# Filter to Colorado (state = 08)
response = cdh.get_data(
include_names=True,
within={"state": "08"}
)
# Filter to Colorado (state = 08)
response = cdh.get_data(
include_names=True,
within={"state": "08"}
)
✅ Variables set:
- Product: American Community Survey: 5-Year Estimates: Detailed Tables 5-Year (2020/acs/acs5) (Vintage: [2020])
Variables: B17001_050E, B17001_051E, B17001_052E, B17001_053E, B17001_054E, B17001_055E, B17001_056E, B17001_057E, B17001_058E, B17001_059E, B17001_040E, B17001_041E, B17001_042E, B17001_043E, B17001_044E, B17001_045E, B17001_046E, B17001_047E, B17001_048E, B17001_049E, B17001_030E, B17001_031E, B17001_032E, B17001_033E, B17001_034E, B17001_035E, B17001_036E, B17001_037E, B17001_038E, B17001_039E, B17001_020E, B17001_021E, B17001_022E, B17001_023E, B17001_024E, B17001_025E, B17001_026E, B17001_027E, B17001_028E, B17001_029E, B17001_018E, B17001_019E, B17001_010E, B17001_011E, B17001_012E, B17001_013E, B17001_014E, B17001_015E, B17001_016E, B17001_017E, B17001_006E, B17001_007E, B17001_008E, B17001_009E, B17001_001E, B17001_002E, B17001_003E, B17001_004E, B17001_005E
- Product: American Community Survey: 5-Year Estimates: Detailed Tables 5-Year (2021/acs/acs5) (Vintage: [2021])
Variables: B17001_050E, B17001_051E, B17001_052E, B17001_053E, B17001_054E, B17001_055E, B17001_056E, B17001_057E, B17001_058E, B17001_059E, B17001_040E, B17001_041E, B17001_042E, B17001_043E, B17001_044E, B17001_045E, B17001_046E, B17001_047E, B17001_048E, B17001_049E, B17001_030E, B17001_031E, B17001_032E, B17001_033E, B17001_034E, B17001_035E, B17001_036E, B17001_037E, B17001_038E, B17001_039E, B17001_020E, B17001_021E, B17001_022E, B17001_023E, B17001_024E, B17001_025E, B17001_026E, B17001_027E, B17001_028E, B17001_029E, B17001_018E, B17001_019E, B17001_010E, B17001_011E, B17001_012E, B17001_013E, B17001_014E, B17001_015E, B17001_016E, B17001_017E, B17001_006E, B17001_007E, B17001_008E, B17001_009E, B17001_001E, B17001_002E, B17001_003E, B17001_004E, B17001_005E
- Product: American Community Survey: 5-Year Estimates: Detailed Tables 5-Year (2022/acs/acs5) (Vintage: [2022])
Variables: B17001_050E, B17001_051E, B17001_052E, B17001_053E, B17001_054E, B17001_055E, B17001_056E, B17001_057E, B17001_058E, B17001_059E, B17001_040E, B17001_041E, B17001_042E, B17001_043E, B17001_044E, B17001_045E, B17001_046E, B17001_047E, B17001_048E, B17001_049E, B17001_030E, B17001_031E, B17001_032E, B17001_033E, B17001_034E, B17001_035E, B17001_036E, B17001_037E, B17001_038E, B17001_039E, B17001_020E, B17001_021E, B17001_022E, B17001_023E, B17001_024E, B17001_025E, B17001_026E, B17001_027E, B17001_028E, B17001_029E, B17001_018E, B17001_019E, B17001_010E, B17001_011E, B17001_012E, B17001_013E, B17001_014E, B17001_015E, B17001_016E, B17001_017E, B17001_006E, B17001_007E, B17001_008E, B17001_009E, B17001_001E, B17001_002E, B17001_003E, B17001_004E, B17001_005E
- Product: ACS 5-Year Detailed Tables (2023/acs/acs5) (Vintage: [2023])
Variables: B17001_050E, B17001_051E, B17001_052E, B17001_053E, B17001_054E, B17001_055E, B17001_056E, B17001_057E, B17001_058E, B17001_059E, B17001_040E, B17001_041E, B17001_042E, B17001_043E, B17001_044E, B17001_045E, B17001_046E, B17001_047E, B17001_048E, B17001_049E, B17001_030E, B17001_031E, B17001_032E, B17001_033E, B17001_034E, B17001_035E, B17001_036E, B17001_037E, B17001_038E, B17001_039E, B17001_020E, B17001_021E, B17001_022E, B17001_023E, B17001_024E, B17001_025E, B17001_026E, B17001_027E, B17001_028E, B17001_029E, B17001_018E, B17001_019E, B17001_010E, B17001_011E, B17001_012E, B17001_013E, B17001_014E, B17001_015E, B17001_016E, B17001_017E, B17001_006E, B17001_007E, B17001_008E, B17001_009E, B17001_001E, B17001_002E, B17001_003E, B17001_004E, B17001_005E
✅ Parameters created for 4 geo-variable/group combinations.
✅ Data fetching complete. Stacking results.
Step 4: Complex Filtering with Tabulate¶
The where parameter supports multiple conditions:
In [4]:
Copied!
response.tabulate(
"NAME",
"B17001_002E", # Below poverty
"B17001_001E", # Total
where=[
"B17001_001E > 1_000", # Population > 1,000
"B17001_002E / B17001_001E < 0.01", # Poverty rate < 1%
"'CDP' not in NAME", # Exclude CDPs
],
weight_var="B17001_001E",
strat_by="vintage" # Separate results by year
)
response.tabulate(
"NAME",
"B17001_002E", # Below poverty
"B17001_001E", # Total
where=[
"B17001_001E > 1_000", # Population > 1,000
"B17001_002E / B17001_001E < 0.01", # Poverty rate < 1%
"'CDP' not in NAME", # Exclude CDPs
],
weight_var="B17001_001E",
strat_by="vintage" # Separate results by year
)
shape: (11, 8) ┌─────────┬─────────────────────────────────┬─────────────┬─────────────┬───────┬──────┬────────┬────────┐ │ vintage ┆ NAME ┆ B17001_002E ┆ B17001_001E ┆ n ┆ pct ┆ cumn ┆ cumpct │ ╞═════════╪═════════════════════════════════╪═════════════╪═════════════╪═══════╪══════╪════════╪════════╡ │ 2020 ┆ Severance town, Colorado ┆ 30 ┆ 5,599 ┆ 5,599 ┆ 66.8 ┆ 5,599 ┆ 66.8 │ │ 2020 ┆ Snowmass Village town, Colorad… ┆ 13 ┆ 2,786 ┆ 2,786 ┆ 33.2 ┆ 8,385 ┆ 100.0 │ │ 2021 ┆ Columbine Valley town, Colorad… ┆ 17 ┆ 1,701 ┆ 1,701 ┆ 13.6 ┆ 1,701 ┆ 13.6 │ │ 2021 ┆ Severance town, Colorado ┆ 55 ┆ 7,681 ┆ 7,681 ┆ 61.6 ┆ 9,382 ┆ 75.2 │ │ 2021 ┆ Snowmass Village town, Colorad… ┆ 11 ┆ 3,089 ┆ 3,089 ┆ 24.8 ┆ 12,471 ┆ 100.0 │ │ 2022 ┆ Columbine Valley town, Colorad… ┆ 17 ┆ 1,928 ┆ 1,928 ┆ 30.0 ┆ 1,928 ┆ 30.0 │ │ 2022 ┆ Nederland town, Colorado ┆ 14 ┆ 1,413 ┆ 1,413 ┆ 22.0 ┆ 3,341 ┆ 52.1 │ │ 2022 ┆ Snowmass Village town, Colorad… ┆ 17 ┆ 3,076 ┆ 3,076 ┆ 47.9 ┆ 6,417 ┆ 100.0 │ │ 2023 ┆ Columbine Valley town, Colorad… ┆ 2 ┆ 2,084 ┆ 2,084 ┆ 19.6 ┆ 2,084 ┆ 19.6 │ │ 2023 ┆ Mead town, Colorado ┆ 54 ┆ 5,503 ┆ 5,503 ┆ 51.7 ┆ 7,587 ┆ 71.3 │ │ 2023 ┆ Snowmass Village town, Colorad… ┆ 0 ┆ 3,048 ┆ 3,048 ┆ 28.7 ┆ 10,635 ┆ 100.0 │ └─────────┴─────────────────────────────────┴─────────────┴─────────────┴───────┴──────┴────────┴────────┘
Tip - Condition Syntax
The
whereparameter supports:
- Simple comparisons:
"AGEP > 17"- Division expressions:
"B17001_002E / B17001_001E < 0.01"- String containment:
"'CDP' not in NAME"