COUNTY EMPLOYMENT & WAGES / PYTHON + CSV
Compare county employment and wages in Python
Add annual employment and wage context to a county market comparison, keeping ownership and disclosure status explicit.
Compare employment and pay across county markets
A dental-equipment supplier is reviewing three North Carolina markets. The QCEW reference adds annual establishment counts, covered jobs and mean pay for private Offices of Dentists, industry 621210. These measures provide local industry context alongside the supplier’s own sales and customer information.
The optional market input CSV contains fictional project labels paired with real county, industry and ownership identifiers. The identical records appear in the markets list in the Python code below. Only the project labels and scenario are invented; all reported statistics come from BLS.
county_industry.csv below is a three-record selection from the purchased reference, with all 17 fields unchanged. Save it in your working folder. The full file contains 991,071 county/industry/ownership records, including 273,531 with disclosed employment and wages. Published establishment counts remain available for the other records.
Code example
Join on county FIPS, industry code and ownership together. Here, ownership 5 selects private employers. The example reads only the requested keys into memory and preserves the source’s rounded values and disclosure status.
Paths are relative to your working folder; use from pathlib import Path; print(Path.cwd()) to check it, or supply full paths.
import csv
from pathlib import Path
folder = Path('.') # Contains county_industry.csv, either sample or full purchase.
# Fictional project labels; the county and industry identifiers are real.
markets = [
{'market': 'Durham comparison', 'county_fips': '37063', 'industry_code': '621210', 'ownership_code': '5'},
{'market': 'Guilford comparison', 'county_fips': '37081', 'industry_code': '621210', 'ownership_code': '5'},
{'market': 'Wake comparison', 'county_fips': '37183', 'industry_code': '621210', 'ownership_code': '5'},
]
key_fields = ('county_fips', 'industry_code', 'ownership_code')
wanted = {tuple(row[k] for k in key_fields) for row in markets}
reference = {}
with (folder / 'county_industry.csv').open(newline='', encoding='utf-8') as f:
for row in csv.DictReader(f):
key = tuple(row[k] for k in key_fields)
if key in wanted:
if key in reference:
raise ValueError(f'Duplicate reference key: {key}')
reference[key] = row
results = []
for market in markets:
row = reference.get(tuple(market[k] for k in key_fields))
result = dict(market)
for field in ('county_name', 'industry_name', 'ownership_name', 'reference_year',
'annual_avg_establishments', 'annual_avg_employment',
'total_annual_wages_usd', 'avg_weekly_wage_usd', 'avg_annual_pay_usd'):
result[field] = row[field] if row else ''
result['employment_wage_status'] = row['employment_wage_status'] if row else 'not_published'
results.append(result)
print(f"{result['county_name'] or market['county_fips']} | "
f"establishments {result['annual_avg_establishments'] or 'unavailable'} | "
f"jobs {result['annual_avg_employment'] or 'unavailable'} | "
f"mean weekly pay USD {result['avg_weekly_wage_usd'] or 'unavailable'} | "
f"{result['employment_wage_status']}")
Analysis of the output
Durham County, North Carolina | establishments 141 | jobs 946 | mean weekly pay USD 1439 | published
Guilford County, North Carolina | establishments 226 | jobs 2090 | mean weekly pay USD 1412 | published
Wake County, North Carolina | establishments 639 | jobs 5637 | mean weekly pay USD 1533 | published
In the 2025 annual source, Wake averages 639 private dental-office establishments and 5,637 covered jobs, compared with Durham’s 141 establishments and 946 jobs. Guilford averages 226 establishments and 2,090 jobs. These are operating locations and workplace jobs, not counts of firms, dentists or unique people.
BLS reports mean weekly pay of $1,533 in Wake, $1,439 in Durham and $1,412 in Guilford. This describes covered payroll across jobs in the industry, including part-time work and covered bonuses; it is not a dentist’s salary, an occupational wage estimate or evidence of prospective customer demand.
For other keys, suppressed means BLS withheld employment and wages. Those measures stay blank while the establishment count remains published. not_published means the key was not found in the file you supplied; check your identifiers and whether you are using the sample or complete download. Neither status means zero activity. Unflagged source zeros remain zero.
Using the full dataset
After purchase, extract the ZIP and set folder to the directory containing its county_industry.csv. Replace the markets list with your own records or load a CSV using csv.DictReader. The displayed example produces the same result against the sample and full file.
county_totals.csv supplies separately published all-industry totals. Ownership 0 is total covered and overlaps the individual ownership categories; do not sum both. County and industry reference tables describe coverage. Use the published totals when you need county totals, rather than adding disclosed detail and treating the sum as complete.
The 2023 County Business Patterns reference adds establishment size bands, but uses 2017 NAICS and mid-March employment with different program coverage. It is not directly comparable to these 2025 annual averages. The NAICS crosswalk helps review classification changes; it does not supply statistical allocation weights. The ACS county profile describes residents over 2020–2024, whereas QCEW counts workplace jobs.
Sources and versions
Source: 2025 BLS QCEW annual averages, based on 2022 NAICS with BLS-specific industry detail. QCEW specialty-trade codes distinguish residential and nonresidential activity; industry_code_type identifies these extensions and unclassified records. Connecticut uses planning regions. This edition covers observed counties and equivalents in the 50 states and DC.
ACD captured the source on October 17, 2026 and prepared this package on 2026-10-17. The retained ZIP’s Last-Modified is August 21, 2026; it is not asserted as an independently verified publication date. These dates are separate from the 2025 reference year.
Free original BLS files · Coverage, annual measures and disclosure · Source scope and preparation record · Our preparation and versioning process.
Example checked October 17, 2026 against both these samples and the complete purchased files. Source and processing records, sample checksums · Expected result CSV. Independent preparation; no agency endorsement.