← Back to list

ZIP It! Census 2020 Data Made Easy — Know Your Population by Geography

If you’ve ever built a predictive model that needed to account for where people live, you know how crucial geographic context can be…

Emma Chung · 2025-04-14 15:33 · 0 claps · 7.9 min read
#census-data #zip-code-analysis #geospatial-data #demographic-analytics #sdoh-data-analytics
Open on Medium ↗
Wiki topics: GRW · Growth & Analytics

ZIP It! Census 2020 Data Made Easy — Know Your Population by Geography

If you’ve ever built a predictive model that needed to account for where people live, you know how crucial geographic context can be. Customer behavior, health outcomes, property values, education metrics — all of these vary dramatically by location, and incorporating this spatial dimension can transform a mediocre model into an exceptional one.

In my own work analyzing regional insurance claim patterns, adding ZIP code level demographic data improved my model’s accuracy by 23%. This isn’t surprising — where people live influences everything from their shopping habits to their health risks.

The U.S. Census 2020 represents the gold standard for such demographic data. In this guide, I’ll show you exactly how to access this treasure trove of information at the ZIP code level, using two approaches:

  1. Direct download from the Census Bureau website (no coding required)
  2. Programmatic access using Python (for data scientists and analysts)

Let’s get started with the easiest approach first.

Method 1: Direct Download from the Census Bureau Website

The Census Bureau provides a user-friendly interface that allows you to select and download specific data tables without writing any code. While this method is straightforward, the interface can be a bit overwhelming if you’re not familiar with it.

Here’s a step-by-step guide

Step 1: Navigate to the Census Data Website

Visit Census data page) and you’ll see the main search interface.

Step 2: Select Your Geography (ZIP Code Tabulation Areas)

  1. In the left sidebar, click on “Geography”
  2. From the dropdown menu, select “ZIP Code Tabulation Area”
  3. Choose “2020” as your year
  4. Under “Select State,” check the box for “All 5-digit ZIP Code Tabulation Areas within United States”
  5. Click “Close” to apply your selection

Important Note: The Census Bureau uses ZIP Code Tabulation Areas (ZCTAs), which approximate USPS ZIP codes but aren’t identical. For most analytical purposes, this distinction isn’t critical, but it’s worth keeping in mind.

Step 3: Select Your Data Tables

Now that you’ve specified the geography, you need to choose which data tables you want to download:

  1. In the search bar at the top, you can search for specific topics (e.g., “income,” “education,” “housing”)
  2. Alternatively, browse through the available tables in the results section
  3. Common tables include:
  • DP02: Selected Social Characteristics
  • DP03: Selected Economic Characteristics
  • DP05: ACS Demographic and Housing Estimates

Step 4: Download Your Data

Once you’ve found the table you want:

  1. Click the download icon in the upper right corner
  2. Select “Download Table Data”
  3. Choose the format (CSV is recommended for most data analysis purposes)
  4. Click “Download”

That’s it! You now have ZIP code level Census data ready for analysis.

Pro Tip: If you’re planning to merge this data with other databases, make sure to keep the “GEOID” column, which contains the standard ZIP code identifier that you can use to join tables.

Method 2: Using Python and the Census API

If you’re comfortable with Python and want more flexibility, programmatic access through the Census API is the way to go. This approach allows you to:

  • Pull only the specific data you need
  • Automate data collection for regular updates
  • Integrate Census data directly into your data pipelines

Let’s break this down into manageable steps:

Step 1: Get an API Key

Before you can access the Census API, you’ll need a free API key:

  1. Visit https://api.census.gov/data/key_signup.html
  2. Fill out the registration form with your email address and organization information
  3. You’ll receive an email with your API key
  4. Click the activation link in the email to activate your key

Step 2: Understand Census Variables

You can find variable names under each group

For example, use

Census Data API:/data/2019/acs/acs5/profile/groups/DP02

You can find variable names under the DP02 group in the Census Data API. You can find the definitions and descriptions of each group on Census Table Codes — Census Reporter

Some commonly used variables include:

  • B01001_001E: Total population
  • B19013_001E: Median household income
  • B25077_001E: Median home value
  • B15003_022E: Population with bachelor's degree

The naming convention follows a pattern:

  • Letter prefix (B = Base Table, S = Subject Table)
  • Topic number (01 = Age/Sex, 19 = Income, etc.)
  • Specific item number
  • Suffix (E = Estimate, M = Margin of Error)

Step 3: Write Python Code to Access the API

Here’s a simple Python script to download ZIP code level population and income data:

import requests
import pandas as pd
import json

# Set your API key
api_key = "YOUR_API_KEY_HERE"
# Define the API endpoint
endpoint = "https://api.census.gov/data/2020/acs/acs5"
# Define the parameters for your query
params = {
    "get": "NAME,B01001_001E,B19013_001E",  # Total population and median household income
    "for": "zip code tabulation area:*",     # All ZIP codes
    "key": api_key
}
# Make the API request
response = requests.get(endpoint, params=params)
# Check if the request was successful
if response.status_code == 200:
    # Parse the JSON response
    data = response.json()

    # Convert to DataFrame
    df = pd.DataFrame(data[1:], columns=data[0])

    # Rename columns for clarity
    df = df.rename(columns={
        "B01001_001E": "total_population",
        "B19013_001E": "median_household_income",
        "zip code tabulation area": "zip_code"
    })

    # Convert numeric columns to appropriate types
    df["total_population"] = pd.to_numeric(df["total_population"])
    df["median_household_income"] = pd.to_numeric(df["median_household_income"])

    # Save to CSV
    df.to_csv("census_zipcode_data.csv", index=False)

    print(f"Successfully downloaded data for {len(df)} ZIP codes")
    print(df.head())
else:
    print(f"Error: {response.status_code}")
    print(response.text)

This script:

  1. Makes a request to the Census API for population and income data
  2. Converts the response to a pandas DataFrame
  3. Renames columns to be more readable
  4. Converts string values to numeric types
  5. Saves the data to a CSV file

Step 4: Using the Census Python Package (Optional)

For more convenience, you can use the census Python package, which simplifies working with the Census API:

# Install with: pip install census us
from census import Census
from us import states
import pandas as pd

# Initialize with your API key
c = Census("YOUR_API_KEY_HERE")
# Get data for all ZIP codes
data = c.acs5.get(
    ("NAME", "B01001_001E", "B19013_001E"),  # Variables 
    {"for": "zip code tabulation area:*"},    # Geography
    year=2020                                # Year
)
# Convert to DataFrame
df = pd.DataFrame(data)
# Rename columns
df = df.rename(columns={
    "B01001_001E": "total_population",
    "B19013_001E": "median_household_income",
    "zip code tabulation area": "zip_code"
})
# Convert to numeric
for col in ["total_population", "median_household_income"]:
    df[col] = pd.to_numeric(df[col], errors="coerce")
# Save to CSV
df.to_csv("census_zipcode_data.csv", index=False)
print(df.head())

This approach is more concise and handles some of the API details for you.

Advanced Technique: Pulling Data by Group

If you need many variables related to the same topic, it’s more efficient to pull them by group rather than listing each variable individually.

For example, to get all variables in the DP02 group (Selected Social Characteristics):

import requests
import pandas as pd

api_key = "YOUR_API_KEY_HERE"
endpoint = "https://api.census.gov/data/2020/acs/acs5/profile"
# Request data by group
params = {
    "get": "group(DP02)",
    "for": "zip code tabulation area:*",
    "key": api_key
}
response = requests.get(endpoint, params=params)
data = response.json()
# The first row contains column names
columns = data[0]
values = data[1:]
# Convert to DataFrame
df = pd.DataFrame(values, columns=columns)
# Save to CSV
df.to_csv("social_characteristics_by_zipcode.csv", index=False)
print(f"Downloaded {len(df)} rows with {len(columns)} columns")

This will give you dozens of variables related to social characteristics in one request.

Visualizing Your Census Data

Once you have your ZIP code level data, visualization can help you understand patterns and relationships. Here’s a simple example using matplotlib and geopandas to create a choropleth map:

import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt

# Load your Census data
census_df = pd.read_csv("census_zipcode_data.csv")
# Load ZIP code shapefile (download from Census TIGER/Line files)
# https://www.census.gov/geographies/mapping-files/time-series/geo/tiger-line-file.html
zip_gdf = gpd.read_file("tl_2020_us_zcta520.shp")
# Convert zip_code column to string
census_df['zip_code'] = census_df['zip_code'].astype(str)
# Merge data
zip_gdf_new = zip_gdf.merge(
    census_df,
    left_on="ZCTA5CE20",  # Column in shapefile
    right_on="zip_code"    # Column in your data
)
# Create the map
fig, ax = plt.subplots(1, figsize=(15, 10))
# Plot median income by ZIP code
zip_gdf_new.plot(
    column="median_household_income",
    cmap="viridis",
    linewidth=0.1,
    ax=ax,
    edgecolor="0.8",
    legend=True
)
# Add title and remove axis
ax.set_title("Median Household Income by ZIP Code", fontsize=16)
ax.set_axis_off()
# Save and show
plt.savefig("income_map.png", dpi=300, bbox_inches="tight")
plt.show()

This will generate a color-coded map displaying median household income across all ZIP codes, as shown below..

Practical Applications

Census data represent a wide range of social and demographic factors known to be relevant to numerous health outcomes and educational attainment measures. When combined with other variables, census-derived information can substantially improve model fit for many predictive modeling applications. Additionally, these data serve as important control variables that help reduce the impact of unobserved confounders, particularly in studies examining Social Determinants of Health (SDOH).

Here are some specific ways you might leverage ZIP code level Census data:

1. Market Analysis

  • Identify areas with your target demographic for store expansion
  • Analyze income patterns to optimize product offerings by region
  • Target marketing efforts based on local population characteristics

2. Real Estate and Housing

  • Analyze neighborhood demographics for investment opportunities
  • Study housing costs relative to local income levels
  • Identify gentrifying areas by tracking changes over time

3. Public Health

  • Map social determinants of health by ZIP code
  • Correlate demographic factors with health outcomes
  • Target public health interventions to vulnerable communities

Handling Common Challenges

While working with Census data, you might encounter some challenges:

1. Missing Values

Some ZIP codes may have missing data, especially for smaller populations:

# Check for missing values
print(df.isna().sum())

# Option 1: Fill with zeros
df = df.fillna(0)
# Option 2: Fill with median values
for col in ["median_household_income", "median_home_value"]:
    df[col] = df[col].fillna(df[col].median())

2. API Rate Limits

The Census API has a limit of 500 queries per IP address per day. For larger projects:

  • Combine variables into fewer queries
  • Cache results locally
  • Implement rate limiting in your code

3. Data Versions

Be aware of which Census product you’re using:

  • Decennial Census (2020): Most accurate count but limited variables
  • American Community Survey (ACS): More detailed but based on sampling
  • 1-year ACS: More current but only for areas with 65,000+ population
  • 5-year ACS: Available for all areas including ZIP codes

Conclusion

ZIP code level Census data provides invaluable context for any analysis that involves geographic patterns. Whether you prefer clicking through the Census website or writing Python code, you now have the tools to access this rich data source.

Remember that while demographic data is powerful, it’s just one piece of the puzzle. The best insights often come from combining Census data with your own domain-specific information.

What will you build with your newly acquired geographic insights?

References

  1. United States Census Bureau. (2021). 2020 Census Data Products. https://www.census.gov/programs-surveys/decennial-census/decade/2020/planning-management/release/about-2020-data-products.html
  2. United States Census Bureau. (2021). Census API User Guide. https://www.census.gov/data/developers/guidance/api-user-guide.html
  3. Krieger, N., Chen, J. T., Waterman, P. D., Soobader, M. J., Subramanian, S. V., & Carson, R. (2002). Geocoding and monitoring of US socioeconomic inequalities in mortality and cancer incidence: Does the choice of area-based measure and geographic level matter?: The Public Health Disparities Geocoding Project. American Journal of Epidemiology, 156(5), 471–482.
  4. Dwyer-Lindgren, L., Bertozzi-Villa, A., Stubbs, R. W., Morozoff, C., Mackenbach, J. P., van Lenthe, F. J., … & Murray, C. J. (2017). Inequalities in life expectancy among US counties, 1980 to 2014: Temporal trends and key drivers. JAMA Internal Medicine, 177(7), 1003–1011.
  5. Singh, G. K. (2003). Area deprivation and widening inequalities in US mortality, 1969–1998. American Journal of Public Health, 93(7), 1137–1143.
  6. Python Software Foundation. (2023). Census Data API Client for Python. https://github.com/datamade/census
  7. Walker, K. (2023). tidycensus: Load US Census Boundary and Attribute Data as ‘tidyverse’ and ‘sf’-Ready Data Frames. R package. https://walker-data.com/tidycensus/
  8. Kolak, M., Bhatt, J., Park, Y. H., Padrón, N. A., & Molefe, A. (2020). Quantification of neighborhood-level social determinants of health in the continental United States. JAMA Network Open, 3(1), e1919928-e1919928.
  9. United States Census Bureau. (2022). Understanding Geographic Identifiers (GEOIDs). https://www.census.gov/programs-surveys/geography/guidance/geo-identifiers.html
  10. Grubesic, T. H., & Matisziw, T. C. (2006). On the use of ZIP codes and ZIP code tabulation areas (ZCTAs) for the spatial analysis of epidemiological data. International Journal of Health Geographics, 5(1), 1–15.
  11. Krieger, N., Waterman, P., Chen, J. T., Soobader, M. J., Subramanian, S. V., & Carson, R. (2002). Zip code caveat: Bias due to spatiotemporal mismatches between zip codes and US census-defined geographic areas — The Public Health Disparities Geocoding Project. American Journal of Public Health, 92(7), 1100–1102.

Interested in learning more about working with geospatial data? Follow me on Medium for upcoming articles on spatial analysis techniques and advanced visualization methods.


메타데이터
post_id
0cd2c26ca2c6
slug
quick-and-easy-ways-to-download-zip-code-level-data-from-census-2020-0cd2c26ca2c6
url
https://medium.com/@hsiaoyin.chung/quick-and-easy-ways-to-download-zip-code-level-data-from-census-2020-0cd2c26ca2c6
canonical_url
https://medium.com/@hsiaoyin.chung/quick-and-easy-ways-to-download-zip-code-level-data-from-census-2020-0cd2c26ca2c6
author_url
https://medium.com/@hsiaoyin.chung
status
ok
fetched_at
2026-08-23 19:11:25