
本文介绍如何利用 Pandas 的 apply() 方法结合结构化映射规则,准确、高效地将数值型 SIC 行业代码(如 15000、70000)批量映射为语义化行业类别(如 "Construction"、"Services"),避免低效的显式循环与索引错误。
本文介绍如何利用 pandas 的 `apply()` 方法结合结构化映射规则,准确、高效地将数值型 sic 行业代码(如 15000、70000)批量映射为语义化行业类别(如 "construction"、"services"),避免低效的显式循环与索引错误。
在数据分析中,常需将原始编码字段(如美国标准产业分类码 SIC)转换为可读性强的业务类别。直接使用嵌套 if 或手动 for 循环遍历 DataFrame 行不仅易出错(如 report['SicCodes'][i] 错误地将值当作索引)、性能低下,还难以维护和调试。
推荐采用 函数封装 + Series.apply() 的范式,既保持逻辑清晰,又充分利用 Pandas 的向量化优势。核心思路是:定义一个纯函数 to_code_range(),接收单个 SIC 值,按预设区间顺序匹配并返回对应行业名;再通过 .apply() 将其广播至整列。
以下是完整、健壮的实现方案:
import pandas as pd
import numpy as np
# 定义 SIC 代码区间到行业类别的映射(左闭右闭)
mappings = [
(1000, 9990, 'Agriculture'),
(10000, 14990, 'Mining'),
(15000, 17990, 'Construction'),
(18000, 19990, 'not used'),
(20000, 39990, 'Manufacturing'),
(40000, 49990, 'Utility Services'),
(50000, 51990, 'Wholesale Trade'),
(52000, 59990, 'Retail Trade'),
(60000, 69200, 'Financials'),
(70000, 90040, 'Services'),
(91000, 97290, 'Public Administration'),
(98000, 99990, 'Nonclassifiable'),
]
def to_code_range(value):
"""将单个 SIC 代码映射为行业名称,支持 int/float 输入,自动处理非数字类型"""
# 类型预检:跳过空值、字符串等非数值类型
if pd.isna(value) or not isinstance(value, (int, float)):
return np.nan
code = int(value) # 强制转为整数(兼容浮点型 SIC 编码)
# 遍历映射区间,返回首个匹配的类别
for code_from, code_to, name in mappings:
if code_from <p><strong>关键改进点说明:</strong> </p>
- ✅ 避免索引错误:原代码 report['SICCode.SicText_1'][i] = ... 试图用 i(即单元格值)作行索引,导致 KeyError;.apply() 自动按行处理,无需手动索引。
- ✅ 增强鲁棒性:新增 pd.isna() 和类型检查,安全处理 None、空字符串、浮点数等常见脏数据,防止 int("None Supplied") 报错。
- ✅ 逻辑精简:删除冗余 if 分支(如重复的 Mining 判断),统一用 for 循环遍历 mappings,便于后期增删区间。
- ✅ 可扩展设计:若未来需支持模糊匹配或正则映射,只需修改 to_code_range() 内部逻辑,不影响主流程。
注意事项:
- 确保 SicCodes 列中无非法字符(如 "12345abc"),否则 int() 会报 ValueError;建议前置清洗:report['SicCodes'] = pd.to_numeric(report['SicCodes'], errors='coerce')。
- 区间定义需严格互斥且覆盖完整(当前存在 9991–9999、14991–14999 等间隙),若业务要求全覆盖,可添加兜底规则或日志告警未匹配值。
- 对超大数据集(千万级),可考虑用 numpy.searchsorted 或 pd.cut() 进一步加速,但需确保区间连续有序。
此方法兼顾可读性、可维护性与执行效率,是工业级数据清洗中处理编码映射任务的标准实践。










