FIPS Codes vs ZIP Codes: Why They're Not the Same
This is one of the most common mistakes in government data analysis: using ZIP codes as a stand-in for county FIPS codes, or assuming they correspond to each other. They don't. ZIP codes and FIPS codes are built for completely different purposes and do not align geographically.
What Each System Is For
FIPS Codes
- Created by: US Census Bureau / NIST
- Purpose: Government data identification
- Geography: Follows political boundaries (states, counties, etc.)
- Stability: Very stable — changes only when political boundaries change
- Format: Fixed-length numeric string (e.g.,
53033)
ZIP Codes
- Created by: US Postal Service (USPS)
- Purpose: Mail delivery routing
- Geography: Follows mail routes, not political lines
- Stability: Frequently updated — added, removed, or reassigned
- Format: 5-digit string (e.g.,
98101)
The Core Problem: ZIP Codes Cross County Lines
ZIP codes are defined by mail delivery routes, not by political boundaries. A single ZIP code can and regularly does span two or more counties. This means you cannot reliably assign a ZIP code to a single FIPS code — it has no one-to-one mapping.
For example, a rural ZIP code in a border area might have 60% of its addresses in one county and 40% in a neighboring county. If you treat that ZIP as belonging to the majority county and then aggregate federal health or economic data by county, you've introduced a systematic error.
When This Error Is Costly
- Public health research: Disease rates, mortality, and health outcomes published at the county FIPS level cannot be validly compared with patient ZIP codes without a crosswalk.
- Economic analysis: BLS employment data is reported by county FIPS. Joining it to ZIP-coded business data directly will misallocate jobs.
- Housing analysis: HUD Fair Market Rents are set by FIPS geography. Mapping them to ZIP codes introduces approximation error.
The Right Tool: HUD ZIP-to-County Crosswalk
The US Department of Housing and Urban Development (HUD) publishes a quarterly ZIP-to-county crosswalk that solves this problem. For every ZIP-county pairing, it provides ratio weights representing what share of that ZIP's addresses fall in each county:
RES_RATIO— share of residential addressesBUS_RATIO— share of business addressesTOT_RATIO— share of all addresses
On each county page on FipsDecoder, we show the ZIP codes that overlap with that county along with their crosswalk ratios, so you can immediately see which ZIP codes to include when working with county-level federal data.
How to Convert: ZIP to FIPS in Python
import pandas as pd
# Load HUD crosswalk (available quarterly from huduser.gov)
xwalk = pd.read_excel('ZIP_COUNTY_122024.xlsx', dtype=str)
xwalk['RES_RATIO'] = xwalk['RES_RATIO'].astype(float)
def zip_to_fips(zip_code: str) -> str:
"""Return the dominant county FIPS for a ZIP code by residential ratio."""
matches = xwalk[xwalk['ZIP'] == zip_code.zfill(5)]
if matches.empty:
return None
return matches.sort_values('RES_RATIO', ascending=False).iloc[0]['COUNTY']
print(zip_to_fips('98101')) # → '53033' (King County, WA)
For weighted analysis (rather than picking one county), iterate over all rows for the ZIP and apply the ratio as a weight to whatever value you're distributing.
Quick Reference
| Question | Answer |
|---|---|
| Can a ZIP code span multiple counties? | Yes, very commonly |
| Can a county contain multiple ZIP codes? | Yes, usually dozens or hundreds |
| Is there a 1-to-1 ZIP ↔ county mapping? | No |
| Can I join ZIP-coded data to county FIPS data directly? | Not without a crosswalk |
| Best tool for ZIP → county conversion? | HUD USPS crosswalk (quarterly) |