INDUSTRY CLASSIFICATION / PYTHON + CSV

NAICS 2017 to 2022 in Python

Prepare updated industry codes for a CRM using the NAICS crosswalk, with titles and a review step for split classifications.

The example and its inputs

Suppose you maintain a CRM whose industry column uses 2017 NAICS codes. You want to prepare a 2022 column for reporting and identify records that need a closer look before updating the CRM.

input.csv contains four fictional company records, repeated in the companies list in the Python code below. The names are invented; the 2017 codes are real. They illustrate a code replacement, a renamed industry, a retained code, and an industry split. Downloading this input CSV is optional because the code includes the records.

crosswalk.csv is a small selection from the paid NAICS 2017 → 2022 Crosswalk. Its five rows are unchanged product records, with all four columns: the code and title for each classification year. All possible 2022 matches for the example’s 2017 codes are included.

01 / SAMPLE DATA

Download the product sample

Use a separate working folder for this example and save this CSV there.

The crosswalk supplies the classification relationships and titles. Your company records supply the business context needed to resolve a split.

02 / PYTHON

Code example

Run this in one Jupyter cell, an IPython session, or a Python script. It uses Python’s standard library. It adds a 2022 code and title when there is one corresponding industry and retains the alternatives when a code splits.

Paths are relative to your working folder; use from pathlib import Path; print(Path.cwd()) to check it, or supply full paths.

Python 3.10+ · Jupyter, IPython or a script
import csv
from collections import defaultdict

# Fictional CRM records, also provided in input.csv. Codes are real 2017 NAICS.
companies = [
    {"company": "Evergreen Software", "naics_2017": "511210"},
    {"company": "Oak Corner Market", "naics_2017": "445120"},
    {"company": "Pine Code Studio", "naics_2017": "541511"},
    {"company": "Riverbend Soil Products", "naics_2017": "325314"},
]

# Keep identifiers as strings. Replace this path with the full CSV after purchase.
with open("crosswalk.csv", newline="", encoding="utf-8-sig") as f:
    crosswalk = list(csv.DictReader(f))

by_2017 = defaultdict(list)
seen = set()
for row in crosswalk:
    key = (row["naics_2017_code"], row["naics_2022_code"])
    if not all(key) or key in seen:
        raise ValueError("Missing or duplicate NAICS code pair")
    seen.add(key)
    by_2017[key[0]].append(row)

results = []
for company in companies:
    matches = by_2017.get(company["naics_2017"], [])
    single = matches[0] if len(matches) == 1 else None
    results.append({
        **company,
        "naics_2022": single["naics_2022_code"] if single else "",
        "title_2022": single["naics_2022_title"] if single else "",
        "status": "single_match" if single else "review_split" if matches else "not_in_reference",
        "candidate_codes": " | ".join(r["naics_2022_code"] for r in matches),
    })

print("Company | 2017 | 2022 | Result")
for row in results:
    print(f'{row["company"]} | {row["naics_2017"]} | '
          f'{row["naics_2022"] or "—"} | {row["status"]}')

print("\n2022 industry titles")
for row in results:
    if row["naics_2022"]:
        print(f'{row["company"]}: {row["title_2022"]}')
    elif row["status"] == "review_split":
        print(f'{row["company"]}: review the activity described by each branch:')
        for match in by_2017[row["naics_2017"]]:
            print(f'  {match["naics_2022_code"]}: {match["naics_2022_title"]}')
            print(f'    From: {match["naics_2017_title"]}')

03 / RESULTS

Analysis of the output

Company | 2017 | 2022 | Result
Evergreen Software | 511210 | 513210 | single_match
Oak Corner Market | 445120 | 445131 | single_match
Pine Code Studio | 541511 | 541511 | single_match
Riverbend Soil Products | 325314 | — | review_split

2022 industry titles
Evergreen Software: Software Publishers
Oak Corner Market: Convenience Retailers
Pine Code Studio: Custom Computer Programming Services
Riverbend Soil Products: review the activity described by each branch:
  325314: Fertilizer (Mixing Only) Manufacturing
    From: Fertilizer (Mixing Only) Manufacturing - except compost manufacturing
  325315: Compost Manufacturing
    From: Fertilizer (Mixing Only) Manufacturing - compost manufacturing

Software Publishers moves from 511210 to 513210. Convenience Stores maps to 445131, Convenience Retailers. Custom Computer Programming Services retains 541511. The results list contains the original company and code alongside the proposed 2022 code, title and status.

Riverbend Soil Products needs review. Its 2017 code, 325314, leads to two 2022 industries: fertilizer mixing and compost manufacturing. The source titles include the activity that distinguishes each branch. The code leaves its proposed 2022 value blank and preserves both choices in candidate_codes. The company’s name alone is not enough to select one.

For your own records, compare the establishment’s activity with the Census NAICS definitions before resolving these cases. A single concordance match is a proposed update based on the existing classification; it does not independently verify that the original code describes the business correctly. An unchanged code and title do not prove the definition is unchanged.

The example keeps one result per CRM record. A not_in_reference result means the code is absent from the CSV you supplied; a small sample cannot evaluate your full CRM’s coverage.

04 / YOUR DATA

Using the full dataset

Replace crosswalk.csv in the open(...) call with ActuallyCleanData_NAICS_2017_to_2022_Crosswalk.csv from the purchased ZIP. Replace the companies list with your own records, or load your CSV:

with open("my-companies.csv", newline="", encoding="utf-8-sig") as f:
    companies = list(csv.DictReader(f))

Use columns named company and naics_2017, or adjust those names in the example. Preserve six-digit codes as text. Insert the CSV-loading lines where the example list appears, then run the rest of the code. Review split and missing results before importing the proposed codes into your CRM.

The full file has 1,150 code pairs, covering 1,057 distinct 2017 codes and 1,012 distinct 2022 codes. Nine 2017 codes have more than one destination. For a larger split, see why 454110 has 42 possible replacements.

Sources and versions

The source is the Census Bureau’s 2022-to-2017 concordance workbook. ACD presents its relationships in the 2017 → 2022 direction as a flat CSV, preserving the branch-specific source titles. The classification editions are 2017 and 2022; the ACD package was produced on 2026-10-13. The production date does not describe a new NAICS edition.

Example checked October 15, 2026 against both these samples and the complete purchased files. Source and processing records, sample checksums · Expected result CSV. Independent preparation; no agency endorsement.