Reference

Reference data lookups: NAICS codes, SOC codes, state FIPS, sample datasets.

Reference data and crosswalks that ship with the library.

  • naics_soc_crosswalk — NAICS / SOC code mapping and crosswalks

  • sample_data — built-in demo datasets (synthetic + real Census mash-ups)

Submodules load on first attribute access via PEP 562 __getattr__.

class siege_utilities.reference.NAICSCode[source]

Bases: object

A NAICS industry code with hierarchy metadata.

code: str
title: str
level: int
parent_code: str | None = None
property sector: str

2-digit sector code.

__init__(code, title, level, parent_code=None)
Parameters:
  • code (str)

  • title (str)

  • level (int)

  • parent_code (str | None)

Return type:

None

siege_utilities.reference.parse_naics(code)[source]

Parse a NAICS code string into a NAICSCode.

Parameters:

code (str) – 2-6 digit NAICS code.

Return type:

NAICSCode

Raises:

ValueError – If the code is not 2-6 digits.

siege_utilities.reference.naics_ancestors(code)[source]

Return ancestor codes from sector down to the given code.

>>> naics_ancestors("541511")
['54', '541', '5415', '54151', '541511']
Parameters:

code (str)

Return type:

list[str]

siege_utilities.reference.naics_to_sector(code)[source]

Return (sector_code, sector_title) for any NAICS code.

Parameters:

code (str)

Return type:

tuple[str, str]

siege_utilities.reference.crosswalk_naics(code, from_year=2017, to_year=2022)[source]

Map a NAICS code from one revision to another.

Parameters:
  • code (str) – Source NAICS code.

  • from_year (int) – Source revision year (2012 or 2017).

  • to_year (int) – Target revision year (2017 or 2022).

Returns:

Target code(s). May be >1 if the source was split. Returns [code] if no mapping is found (assumed unchanged).

Return type:

list of str

class siege_utilities.reference.SOCCode[source]

Bases: object

A Standard Occupational Classification code.

code: str
title: str
level: str
property major_group: str

2-digit major group (e.g., “11” from “11-1011”).

__init__(code, title, level)
Parameters:
Return type:

None

siege_utilities.reference.parse_soc(code)[source]

Parse an SOC code string.

Parameters:

code (str) – SOC code in "XX-XXXX" format or just the major group "XX".

Return type:

SOCCode

siege_utilities.reference.soc_to_major_group(code)[source]

Return (major_code, title) for any SOC code.

Parameters:

code (str)

Return type:

tuple[str, str]

siege_utilities.reference.fuzzy_match_naics(text, candidates=None, threshold=0.5)[source]

Simple token-overlap fuzzy match of text against NAICS sector titles.

Parameters:
  • text (str) – Free-text industry description (e.g., from NLRB filings).

  • candidates (dict, optional) – {code: title} mapping. Defaults to NAICS_SECTORS.

  • threshold (float) – Minimum similarity score (0-1) to include.

Returns:

Sorted by score descending.

Return type:

list of (code, title, score)

siege_utilities.reference.get_naics_lookup()[source]

Return a combined NAICS lookup table (sectors + subsectors).

Returns:

Dict mapping NAICS codes to titles at all available levels.

Return type:

dict[str, str]

siege_utilities.reference.get_soc_lookup()[source]

Return a combined SOC lookup table (major groups + minor groups).

Returns:

Dict mapping SOC codes to titles at all available levels.

Return type:

dict[str, str]

siege_utilities.reference.naics_title(code)[source]

Look up the title for a NAICS code at any level.

Checks subsector-level first, then falls back to sector. Returns ‘Unknown’ if not found.

Parameters:

code (str)

Return type:

str

siege_utilities.reference.soc_title(code)[source]

Look up the title for an SOC code at any level.

Checks minor-group level first, then falls back to major group. Returns ‘Unknown’ if not found.

Parameters:

code (str)

Return type:

str

siege_utilities.reference.filter_by_naics(records, naics_prefix)[source]

Filter NLRB case records by NAICS code prefix.

Works with any iterable of objects that have a naics_code attribute (NLRBCaseRecord, NLRBCase model instances, or dicts with ‘naics_code’).

Parameters:
  • records – Iterable of records to filter.

  • naics_prefix (str) – NAICS prefix to match (e.g., ‘622’ for hospitals, ‘62’ for all health care).

Returns:

List of matching records.

Return type:

list

Example:

# Show all elections in NAICS 622 (hospitals)
hospital_cases = filter_by_naics(result.cases, "622")
siege_utilities.reference.filter_by_naics_sector(records, sector_code)[source]

Filter records by 2-digit NAICS sector code.

Parameters:

sector_code (str)

Return type:

list

siege_utilities.reference.group_by_naics_sector(records)[source]

Group records by their 2-digit NAICS sector code.

Returns:

Dict mapping sector codes to lists of records. Records without a NAICS code are grouped under ‘’.

Return type:

dict[str, list]

siege_utilities.reference.list_available_datasets()[source]

List all available sample datasets with descriptions and metadata.

Returns:

Dictionary of available datasets with metadata

Return type:

Dict[str, Dict[str, Any]]

siege_utilities.reference.get_dataset_info(dataset_name)[source]

Get detailed information about a specific dataset.

Parameters:

dataset_name (str) – Name of the dataset

Returns:

Dataset information dictionary or None if not found

Return type:

Dict[str, Any] | None

siege_utilities.reference.load_sample_data(dataset_name, **kwargs)[source]

Load a sample dataset by name.

Parameters:
  • dataset_name (str) – Name of the dataset to load

  • **kwargs – Additional arguments for dataset generation

Returns:

DataFrame or GeoDataFrame with sample data

Raises:
  • ValueError – If dataset name is not recognized

  • ImportError – If required dependencies are not available

Return type:

pandas.DataFrame | geopandas.GeoDataFrame

siege_utilities.reference.get_census_boundaries(year=2020, geographic_level='tract', state_fips=None, county_fips=None)[source]

Download Census geographic boundaries.

Parameters:
  • year (int) – Census year (default: 2020)

  • geographic_level (str) – Geographic level (state, county, tract, etc.)

  • state_fips (str | None) – State FIPS code for filtering

  • county_fips (str | None) – County FIPS code for filtering (if applicable)

Returns:

GeoDataFrame with boundaries.

Raises:
  • ImportError – If geo extras are not installed.

  • RuntimeError – If no boundaries are returned from Census source.

Return type:

geopandas.GeoDataFrame

siege_utilities.reference.get_census_data(year=2020, data_type='demographics', geographic_level='tract', state_fips=None, county_fips=None)[source]

Get Census demographic/attribute data.

Parameters:
  • year (int) – Census year (default: 2020)

  • data_type (str) – Type of data (demographics, housing, income, etc.)

  • geographic_level (str) – Geographic level for data

  • state_fips (str | None) – State FIPS code for filtering

  • county_fips (str | None) – County FIPS code for filtering

Returns:

DataFrame with Census data or None if failed

Return type:

pandas.DataFrame | None

siege_utilities.reference.join_boundaries_and_data(boundaries, data, boundary_id_col='geoid', data_id_col='geoid')[source]

Join geographic boundaries with attribute data.

Parameters:
  • boundaries (geopandas.GeoDataFrame) – GeoDataFrame with geographic boundaries

  • data (pandas.DataFrame) – DataFrame with attribute data

  • boundary_id_col (str) – Column name for boundary identifiers

  • data_id_col (str) – Column name for data identifiers

Returns:

GeoDataFrame with joined data.

Raises:
  • KeyError – If the specified ID columns do not exist.

  • ValueError – If the join produces zero records.

Return type:

geopandas.GeoDataFrame

siege_utilities.reference.create_sample_dataset(year=2020, geographic_level='tract', state_fips='06', county_fips='037', include_geometry=True)[source]

Create a real-world sample dataset by combining boundaries and data.

Parameters:
  • year (int) – Census year

  • geographic_level (str) – Geographic level

  • state_fips (str) – State FIPS code

  • county_fips (str) – County FIPS code

  • include_geometry (bool) – Whether to include geographic boundaries

Returns:

Combined dataset.

Raises:
Return type:

pandas.DataFrame | geopandas.GeoDataFrame

siege_utilities.reference.get_census_county_sample(state_fips='06', county_fips='037', tract_count=5)[source]

Generate a sample county dataset with multiple tracts and synthetic data.

Parameters:
  • state_fips (str) – State FIPS code (default: CA)

  • county_fips (str) – County FIPS code (default: Los Angeles)

  • tract_count (int) – Number of tracts to include

Returns:

DataFrame or GeoDataFrame with county data

Return type:

pandas.DataFrame | geopandas.GeoDataFrame

siege_utilities.reference.get_metropolitan_sample(cbsa_code='31080', county_count=3)[source]

Generate a metropolitan area sample with multiple counties.

Parameters:
  • cbsa_code (str) – CBSA code (default: Los Angeles metro)

  • county_count (int) – Number of counties to include

Returns:

DataFrame or GeoDataFrame with metro data

Return type:

pandas.DataFrame | geopandas.GeoDataFrame

siege_utilities.reference.generate_synthetic_population(demographics=None, size=1000, geography_level='tract', tract_info=None, include_names=True, include_addresses=True, include_income=True, include_education=True)[source]

Generate synthetic population data matching real demographic patterns.

Parameters:
  • demographics (Dict | None) – Dictionary of demographic percentages

  • size (int) – Number of people to generate

  • geography_level (str) – Geographic level (tract, county, etc.)

  • tract_info (Dict | None) – Additional tract information

  • include_names (bool) – Whether to include synthetic names

  • include_addresses (bool) – Whether to include synthetic addresses

  • include_income (bool) – Whether to include synthetic income

  • include_education (bool) – Whether to include synthetic education

Returns:

DataFrame with synthetic population data

Return type:

pandas.DataFrame

siege_utilities.reference.generate_synthetic_businesses(business_count=500, industry_distribution=None, include_locations=True)[source]

Generate synthetic business data with realistic industry patterns.

Parameters:
  • business_count (int) – Number of businesses to generate

  • industry_distribution (Dict | None) – Dictionary of industry percentages

  • include_locations (bool) – Whether to include synthetic addresses

Returns:

DataFrame with synthetic business data

Return type:

pandas.DataFrame

siege_utilities.reference.generate_synthetic_housing(housing_count=300, property_types=None, include_coordinates=True, locale='us', lat_range=None, lon_range=None, area_unit=None, area_range=None, value_range=None)[source]

Generate synthetic housing data with realistic property patterns.

Parameters:
  • housing_count (int) – Number of housing units to generate

  • property_types (Dict | None) – Dictionary of property type percentages. If None, uses locale-appropriate defaults.

  • include_coordinates (bool) – Whether to include synthetic coordinates

  • locale (str) – Country/region preset (‘us’, ‘uk’, ‘de’, ‘fr’, ‘au’). Controls address format, coordinate bounds, units, and value ranges.

  • lat_range (Tuple[float, float] | None) – Override latitude bounds (min, max)

  • lon_range (Tuple[float, float] | None) – Override longitude bounds (min, max)

  • area_unit (str | None) – Override area column name (e.g. ‘square_feet’, ‘square_metres’)

  • area_range (Tuple[int, int] | None) – Override area range (min, max)

  • value_range (Tuple[int, int] | None) – Override property value range (min, max)

Returns:

DataFrame with synthetic housing data

Return type:

pandas.DataFrame

Submodules

NAICS and SOC code crosswalk and normalization.

Maps NLRB industry/occupation codes to Census classification systems:

  • NAICS (North American Industry Classification System): 2-6 digit hierarchical industry codes with revision crosswalks (2012 → 2017 → 2022).

  • SOC (Standard Occupational Classification): 2-6 digit occupation codes with revision crosswalks (2010 → 2018).

Used by the cross-tabulation engine (siege_utilities.data.cross_tabulation) to join NLRB bargaining-unit data with Census industry/occupation tables.

class siege_utilities.reference.naics_soc_crosswalk.NAICSCode[source]

Bases: object

A NAICS industry code with hierarchy metadata.

code: str
title: str
level: int
parent_code: str | None = None
property sector: str

2-digit sector code.

__init__(code, title, level, parent_code=None)
Parameters:
  • code (str)

  • title (str)

  • level (int)

  • parent_code (str | None)

Return type:

None

siege_utilities.reference.naics_soc_crosswalk.parse_naics(code)[source]

Parse a NAICS code string into a NAICSCode.

Parameters:

code (str) – 2-6 digit NAICS code.

Return type:

NAICSCode

Raises:

ValueError – If the code is not 2-6 digits.

siege_utilities.reference.naics_soc_crosswalk.naics_ancestors(code)[source]

Return ancestor codes from sector down to the given code.

>>> naics_ancestors("541511")
['54', '541', '5415', '54151', '541511']
Parameters:

code (str)

Return type:

list[str]

siege_utilities.reference.naics_soc_crosswalk.naics_to_sector(code)[source]

Return (sector_code, sector_title) for any NAICS code.

Parameters:

code (str)

Return type:

tuple[str, str]

siege_utilities.reference.naics_soc_crosswalk.crosswalk_naics(code, from_year=2017, to_year=2022)[source]

Map a NAICS code from one revision to another.

Parameters:
  • code (str) – Source NAICS code.

  • from_year (int) – Source revision year (2012 or 2017).

  • to_year (int) – Target revision year (2017 or 2022).

Returns:

Target code(s). May be >1 if the source was split. Returns [code] if no mapping is found (assumed unchanged).

Return type:

list of str

class siege_utilities.reference.naics_soc_crosswalk.SOCCode[source]

Bases: object

A Standard Occupational Classification code.

code: str
title: str
level: str
property major_group: str

2-digit major group (e.g., “11” from “11-1011”).

__init__(code, title, level)
Parameters:
Return type:

None

siege_utilities.reference.naics_soc_crosswalk.parse_soc(code)[source]

Parse an SOC code string.

Parameters:

code (str) – SOC code in "XX-XXXX" format or just the major group "XX".

Return type:

SOCCode

siege_utilities.reference.naics_soc_crosswalk.soc_to_major_group(code)[source]

Return (major_code, title) for any SOC code.

Parameters:

code (str)

Return type:

tuple[str, str]

siege_utilities.reference.naics_soc_crosswalk.fuzzy_match_naics(text, candidates=None, threshold=0.5)[source]

Simple token-overlap fuzzy match of text against NAICS sector titles.

Parameters:
  • text (str) – Free-text industry description (e.g., from NLRB filings).

  • candidates (dict, optional) – {code: title} mapping. Defaults to NAICS_SECTORS.

  • threshold (float) – Minimum similarity score (0-1) to include.

Returns:

Sorted by score descending.

Return type:

list of (code, title, score)

siege_utilities.reference.naics_soc_crosswalk.get_naics_lookup()[source]

Return a combined NAICS lookup table (sectors + subsectors).

Returns:

Dict mapping NAICS codes to titles at all available levels.

Return type:

dict[str, str]

siege_utilities.reference.naics_soc_crosswalk.get_soc_lookup()[source]

Return a combined SOC lookup table (major groups + minor groups).

Returns:

Dict mapping SOC codes to titles at all available levels.

Return type:

dict[str, str]

siege_utilities.reference.naics_soc_crosswalk.naics_title(code)[source]

Look up the title for a NAICS code at any level.

Checks subsector-level first, then falls back to sector. Returns ‘Unknown’ if not found.

Parameters:

code (str)

Return type:

str

siege_utilities.reference.naics_soc_crosswalk.soc_title(code)[source]

Look up the title for an SOC code at any level.

Checks minor-group level first, then falls back to major group. Returns ‘Unknown’ if not found.

Parameters:

code (str)

Return type:

str

siege_utilities.reference.naics_soc_crosswalk.filter_by_naics(records, naics_prefix)[source]

Filter NLRB case records by NAICS code prefix.

Works with any iterable of objects that have a naics_code attribute (NLRBCaseRecord, NLRBCase model instances, or dicts with ‘naics_code’).

Parameters:
  • records – Iterable of records to filter.

  • naics_prefix (str) – NAICS prefix to match (e.g., ‘622’ for hospitals, ‘62’ for all health care).

Returns:

List of matching records.

Return type:

list

Example:

# Show all elections in NAICS 622 (hospitals)
hospital_cases = filter_by_naics(result.cases, "622")
siege_utilities.reference.naics_soc_crosswalk.filter_by_naics_sector(records, sector_code)[source]

Filter records by 2-digit NAICS sector code.

Parameters:

sector_code (str)

Return type:

list

siege_utilities.reference.naics_soc_crosswalk.group_by_naics_sector(records)[source]

Group records by their 2-digit NAICS sector code.

Returns:

Dict mapping sector codes to lists of records. Records without a NAICS code are grouped under ‘’.

Return type:

dict[str, list]

Sample Data Generation and Management

This module provides built-in sample datasets for testing, learning, and demonstration purposes. Combines real Census data with synthetic personal data using Faker for realistic datasets.

siege_utilities.reference.sample_data.list_available_datasets()[source]

List all available sample datasets with descriptions and metadata.

Returns:

Dictionary of available datasets with metadata

Return type:

Dict[str, Dict[str, Any]]

siege_utilities.reference.sample_data.get_dataset_info(dataset_name)[source]

Get detailed information about a specific dataset.

Parameters:

dataset_name (str) – Name of the dataset

Returns:

Dataset information dictionary or None if not found

Return type:

Dict[str, Any] | None

siege_utilities.reference.sample_data.load_sample_data(dataset_name, **kwargs)[source]

Load a sample dataset by name.

Parameters:
  • dataset_name (str) – Name of the dataset to load

  • **kwargs – Additional arguments for dataset generation

Returns:

DataFrame or GeoDataFrame with sample data

Raises:
  • ValueError – If dataset name is not recognized

  • ImportError – If required dependencies are not available

Return type:

pandas.DataFrame | geopandas.GeoDataFrame

siege_utilities.reference.sample_data.get_census_boundaries(year=2020, geographic_level='tract', state_fips=None, county_fips=None)[source]

Download Census geographic boundaries.

Parameters:
  • year (int) – Census year (default: 2020)

  • geographic_level (str) – Geographic level (state, county, tract, etc.)

  • state_fips (str | None) – State FIPS code for filtering

  • county_fips (str | None) – County FIPS code for filtering (if applicable)

Returns:

GeoDataFrame with boundaries.

Raises:
  • ImportError – If geo extras are not installed.

  • RuntimeError – If no boundaries are returned from Census source.

Return type:

geopandas.GeoDataFrame

siege_utilities.reference.sample_data.get_census_data(year=2020, data_type='demographics', geographic_level='tract', state_fips=None, county_fips=None)[source]

Get Census demographic/attribute data.

Parameters:
  • year (int) – Census year (default: 2020)

  • data_type (str) – Type of data (demographics, housing, income, etc.)

  • geographic_level (str) – Geographic level for data

  • state_fips (str | None) – State FIPS code for filtering

  • county_fips (str | None) – County FIPS code for filtering

Returns:

DataFrame with Census data or None if failed

Return type:

pandas.DataFrame | None

siege_utilities.reference.sample_data.join_boundaries_and_data(boundaries, data, boundary_id_col='geoid', data_id_col='geoid')[source]

Join geographic boundaries with attribute data.

Parameters:
  • boundaries (geopandas.GeoDataFrame) – GeoDataFrame with geographic boundaries

  • data (pandas.DataFrame) – DataFrame with attribute data

  • boundary_id_col (str) – Column name for boundary identifiers

  • data_id_col (str) – Column name for data identifiers

Returns:

GeoDataFrame with joined data.

Raises:
  • KeyError – If the specified ID columns do not exist.

  • ValueError – If the join produces zero records.

Return type:

geopandas.GeoDataFrame

siege_utilities.reference.sample_data.create_sample_dataset(year=2020, geographic_level='tract', state_fips='06', county_fips='037', include_geometry=True)[source]

Create a real-world sample dataset by combining boundaries and data.

Parameters:
  • year (int) – Census year

  • geographic_level (str) – Geographic level

  • state_fips (str) – State FIPS code

  • county_fips (str) – County FIPS code

  • include_geometry (bool) – Whether to include geographic boundaries

Returns:

Combined dataset.

Raises:
Return type:

pandas.DataFrame | geopandas.GeoDataFrame

siege_utilities.reference.sample_data.get_census_county_sample(state_fips='06', county_fips='037', tract_count=5)[source]

Generate a sample county dataset with multiple tracts and synthetic data.

Parameters:
  • state_fips (str) – State FIPS code (default: CA)

  • county_fips (str) – County FIPS code (default: Los Angeles)

  • tract_count (int) – Number of tracts to include

Returns:

DataFrame or GeoDataFrame with county data

Return type:

pandas.DataFrame | geopandas.GeoDataFrame

siege_utilities.reference.sample_data.get_metropolitan_sample(cbsa_code='31080', county_count=3)[source]

Generate a metropolitan area sample with multiple counties.

Parameters:
  • cbsa_code (str) – CBSA code (default: Los Angeles metro)

  • county_count (int) – Number of counties to include

Returns:

DataFrame or GeoDataFrame with metro data

Return type:

pandas.DataFrame | geopandas.GeoDataFrame

siege_utilities.reference.sample_data.generate_synthetic_population(demographics=None, size=1000, geography_level='tract', tract_info=None, include_names=True, include_addresses=True, include_income=True, include_education=True)[source]

Generate synthetic population data matching real demographic patterns.

Parameters:
  • demographics (Dict | None) – Dictionary of demographic percentages

  • size (int) – Number of people to generate

  • geography_level (str) – Geographic level (tract, county, etc.)

  • tract_info (Dict | None) – Additional tract information

  • include_names (bool) – Whether to include synthetic names

  • include_addresses (bool) – Whether to include synthetic addresses

  • include_income (bool) – Whether to include synthetic income

  • include_education (bool) – Whether to include synthetic education

Returns:

DataFrame with synthetic population data

Return type:

pandas.DataFrame

siege_utilities.reference.sample_data.generate_synthetic_businesses(business_count=500, industry_distribution=None, include_locations=True)[source]

Generate synthetic business data with realistic industry patterns.

Parameters:
  • business_count (int) – Number of businesses to generate

  • industry_distribution (Dict | None) – Dictionary of industry percentages

  • include_locations (bool) – Whether to include synthetic addresses

Returns:

DataFrame with synthetic business data

Return type:

pandas.DataFrame

siege_utilities.reference.sample_data.generate_synthetic_housing(housing_count=300, property_types=None, include_coordinates=True, locale='us', lat_range=None, lon_range=None, area_unit=None, area_range=None, value_range=None)[source]

Generate synthetic housing data with realistic property patterns.

Parameters:
  • housing_count (int) – Number of housing units to generate

  • property_types (Dict | None) – Dictionary of property type percentages. If None, uses locale-appropriate defaults.

  • include_coordinates (bool) – Whether to include synthetic coordinates

  • locale (str) – Country/region preset (‘us’, ‘uk’, ‘de’, ‘fr’, ‘au’). Controls address format, coordinate bounds, units, and value ranges.

  • lat_range (Tuple[float, float] | None) – Override latitude bounds (min, max)

  • lon_range (Tuple[float, float] | None) – Override longitude bounds (min, max)

  • area_unit (str | None) – Override area column name (e.g. ‘square_feet’, ‘square_metres’)

  • area_range (Tuple[int, int] | None) – Override area range (min, max)

  • value_range (Tuple[int, int] | None) – Override property value range (min, max)

Returns:

DataFrame with synthetic housing data

Return type:

pandas.DataFrame