Jupyter中SicCodes列映射公司类别:循环实现遇错求优化
问题解决:DataFrame列值的SIC编码区间映射优化
问题分析
你当前的代码存在两个核心问题:
- 自定义函数
to_code_range仅支持单个值处理,无法直接作用于整个Series(DataFrame列) - 遍历赋值时误用了列值作为索引(
report['SICCode.SicText_1'][i]中的i是SicCodes的取值,不是DataFrame的索引),导致赋值报错
同时,原函数存在冗余(重复的Mining判断)、类型处理不严谨(未处理"None Supplied"这类字符串值)的问题。
优化方案
方案1:使用pandas.Series.apply(简单直观)
先修正to_code_range函数,完善类型处理和逻辑,再用apply批量处理整列:
import numpy as np import pandas as pd 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(valeur): # 处理空值或指定字符串 if pd.isna(valeur) or valeur == "None Supplied": return np.nan # 尝试转换为整数,捕获异常 try: code = int(valeur) except (ValueError, TypeError): print(f"无法转换为整数:{valeur}") return np.nan # 遍历映射区间匹配 for code_from, code_to, name in mappings: if code_from <= code <= code_to: return name # 不在任何区间的返回空值 return np.nan # 批量处理整列 report['SICCode.SicText_1'] = report['SicCodes'].apply(to_code_range)
方案2:使用pd.cut(性能更优,适合大数据集)
对于区间映射场景,pandas.cut是矢量化操作,比apply效率高很多,尤其当数据量较大时:
import pandas as pd import numpy as np # 提取区间边界和对应类别 bins = [-np.inf] + [x[0] for x in mappings] + [np.inf] labels = [x[2] for x in mappings] # 先处理SicCodes列的类型转换,异常值转为空值 report['SicCodes_clean'] = pd.to_numeric(report['SicCodes'], errors='coerce') # 使用cut完成区间映射 report['SICCode.SicText_1'] = pd.cut( report['SicCodes_clean'], bins=bins, labels=labels, include_lowest=True ) # 可选:删除中间辅助列 report.drop('SicCodes_clean', axis=1, inplace=True)
关键改进点
- 类型安全:增加异常捕获,处理非数值、空值、"None Supplied"等特殊情况
- 避免索引错误:使用pandas原生批量处理方法,不再手动遍历赋值
- 性能优化:方案2的
pd.cut是矢量化操作,比循环/apply效率提升一个数量级 - 代码简洁:复用
mappings列表,避免重复的if判断逻辑
内容的提问来源于stack exchange,提问作者Florian
相关产品推荐
相关产品推荐

