Skip to main content

A Python package to process and extract features from zipcode data.

Project description

zipcode features

similar to uszipcode-project

Getting CBSA mapping

If you need CBSA data you can append it to the dataframe with the following example:

from zipcode_features import us_get_demographics
import pandas as pd

def _get_cbsa_data():
    return pd.read_excel(
        "https://github.com/EricSchles/zipcode_features/raw/refs/heads/main/zipcode_features/CBSA_ZIP_122025.xlsx",
        sheet_name='Export Worksheet'
    )[["CBSA", "ZIP"]]

demo = us_get_demographics(state="NY")
cbsa_zip_map = _get_cbsa_data()
df = pd.merge(demo, cbsa_zip_map, how="left", left_on="zipcode", right_on="ZIP")

For the semantic names you can get them here.

Here's a python script to parse them:

import urllib.request
import PyPDF2
import json
import re
import io

def fetch_cbsa_to_json():
    url = "https://www2.census.gov/programs-surveys/cps/methodology/2015%20Geography%20Cover.pdf"
    
    print("Downloading Census PDF...")
    # Using a User-Agent to ensure the request isn't blocked by the server
    req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
    
    try:
        response = urllib.request.urlopen(req)
        pdf_bytes = io.BytesIO(response.read())
    except Exception as e:
        print(f"Failed to download PDF: {e}")
        return

    print("Parsing PDF...")
    reader = PyPDF2.PdfReader(pdf_bytes)
    
    cbsa_mapping = {}
    
    # Regular expression to match a 5-digit FIPS/CBSA code followed by the area name
    # Example match: "11460 Ann Arbor, MI"
    pattern = re.compile(r'\b(\d{5})\s+(.+?)(?=\s+\d{5}|\n|$)')
    
    for page in reader.pages:
        text = page.extract_text()
        if text:
            matches = pattern.findall(text)
            for code, name in matches:
                # Clean up any trailing spaces or artifacts
                clean_name = name.strip()
                # Exclude standalone numbers or random headers that might get caught
                if len(clean_name) > 2 and not clean_name.isdigit():
                    cbsa_mapping[code] = clean_name
                    
    print(f"Extracted {len(cbsa_mapping)} CBSA codes.")
    
    # Save the mapping to a JSON file
    output_file = 'cbsa_codes.json'
    with open(output_file, 'w', encoding='utf-8') as f:
        json.dump(cbsa_mapping, f, indent=4)
        
    print(f"Successfully saved to {output_file}")

if __name__ == "__main__":
    fetch_cbsa_to_json()

Here's a working example for using this with the above:

import requests
from zipcode_features import us_get_demographics
import pandas as pd

def _get_cbsa_data():
    return pd.read_excel(
        "https://github.com/EricSchles/zipcode_features/raw/refs/heads/main/zipcode_features/CBSA_ZIP_122025.xlsx",
        sheet_name='Export Worksheet'
    )[["CBSA", "ZIP"]]

demo = us_get_demographics(state="NY")
cbsa_zip_map = _get_cbsa_data()
df = pd.merge(demo, cbsa_zip_map, how="left", left_on="zipcode", right_on="ZIP")
df = df.drop("ZIP", axis=1)
mapping = requests.get("https://raw.githubusercontent.com/EricSchles/zipcode_features/refs/heads/main/zipcode_features/cbsa_codes.json").json()
df["cbsa_name"] = df["CBSA"].map(mapping)
df = df.drop("CBSA", axis=1)

Adding County

from zipcode_features import us_get_demographics
import pandas as pd

def _get_fips_data():
    df = pd.read_excel(
        "https://github.com/EricSchles/zipcode_features/raw/refs/heads/main/zipcode_features/ZIP_COUNTY_122025.xlsx",
	dtype={'ZIP': 'str'},
        sheet_name='Export Worksheet'
    )[["COUNTY", "ZIP"]]
    df["COUNTY"] = df['COUNTY'].astype(str)
    return df.dropna()

demo = us_get_demographics(state="NY")
fips_zip_map = _get_fips_data()
df = pd.merge(demo, fips_zip_map, how="left", left_on="zipcode", right_on="ZIP")
df = df.drop("ZIP", axis=1)
df = df.dropna()

Adding Regional Prices

python -m pip install beaapi us
from zipcode_features import us_get_demographics
import pandas as pd
import beaapi
import us

df = us_get_demographics(state="NY")

# get your key here: https://apps.bea.gov/API/signup/
beakey = ""

dataset="Regional"
table = "SARPP"
regional_cpi = beaapi.get_data(
    userid=beakey,
    method='GetData',
    datasetname=dataset, # National Income and Product Accounts
    tablename=table, # Table 1.1.1
    GeoFips="STATE",
    LineCode="1",
    ResultFormat="json"
    #Frequency='A',      # Annual data
)[["GeoName", "DataValue"]]
regional_cpi = regional_cpi[regional_cpi["GeoName"] != "United States"]
regional_cpi["year"] = ["2020", "2021", "2022", "2023", "2024"] * 51
abbreviations_map = us.states.mapping('name', 'abbr')
regional_cpi["state"] = regional_cpi["GeoName"].map(abbreviations_map)
regional_cpi["cpi"] = regional_cpi["DataValue"]
regional_cpi = regional_cpi.drop("DataValue", axis=1)
regional_cpi = regional_cpi[regional_cpi["year"] == "2024"]
regional_cpi["cpi_year"] = regional_cpi["year"]
regional_cpi.drop("year", axis=1)
df = pd.merge(df, regional_cpi, how='left', on="state")
df["regional_cpi"] = df["cpi"]
df = df.drop("cpi", axis=1)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zipcode_features-0.1.3.tar.gz (8.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zipcode_features-0.1.3-py3-none-any.whl (8.0 MB view details)

Uploaded Python 3

File details

Details for the file zipcode_features-0.1.3.tar.gz.

File metadata

  • Download URL: zipcode_features-0.1.3.tar.gz
  • Upload date:
  • Size: 8.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.2

File hashes

Hashes for zipcode_features-0.1.3.tar.gz
Algorithm Hash digest
SHA256 365ce400f61d282012102bc458108ff0ccef0f3e7f9deed25289902cae631a7a
MD5 cf9c3c7afc6ed4cad35e40d868a3d468
BLAKE2b-256 a6d7c52d9e5a957b85b4c81829ba2c9ad922479da88ddbac410a5c53f38b9623

See more details on using hashes here.

File details

Details for the file zipcode_features-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for zipcode_features-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 513ed8c41dabfb5053515118774a8df135990b7c353cbda736d4fe06030e28aa
MD5 0982d5596d9b1833301ad64d57c2f285
BLAKE2b-256 98c76f3d7be6d07dbaf58814410681f6dbacc61494c37a61815f10d8dddf561f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page