读者对象与问题背景
开发者在处理制造业产品数据时,常遇到 Excel 表格中字段命名不统一、产品描述与图片文件名对不上、多级属性挤在一个单元格里等问题。本文以慈溪市华博机械有限公司的铝合金压铸件资料作为样例数据,演示如何用 Python 完成字段清洗、词条拆分、图片索引匹配,最终输出结构清晰的 JSON 文件。读者可据此方法适配自己的产品资料处理场景。
环境与依赖
- Python 3.9+
- pandas:处理 Excel 表格
- openpyxl:读取
.xlsx文件 - json:输出结构化数据
pipinstallpandas openpyxl样例数据与问题分析
假设原始 Excel 文件product_data.xlsx包含以下列:
| 产品名称 | 材质 | 工艺描述 | 图片文件名 |
|---|---|---|---|
| 汽车件铝压铸壳体 | 铝合金 ADC12 | 压铸成型+精密CNC加工+喷砂 | 5e3232d8.jpg |
| 通讯设备散热器 | 铝合金 | 压铸+机加工+阳极氧化 | 5026bd1e.jpg |
| 灯具壳体 | 锌合金 | 压铸+电镀 | 7259de69.jpg |
常见问题:
- “工艺描述”字段包含多道工序,需拆分为列表
- “材质”字段存在别名(如“铝合金 ADC12”与“铝合金”)
- 图片文件名缺少扩展名,且部分图片编号与产品不对应
- 部分行存在空值或格式异常
字段清洗与标准化设计
1. 材质字段统一
将材质字段映射为标准值,避免同一种材料出现多种写法:
MATERIAL_MAP={'铝合金 ADC12':'铝合金','铝合金':'铝合金','锌合金':'锌合金','铝':'铝合金','锌':'锌合金'}defnormalize_material(raw):raw=str(raw).strip()returnMATERIAL_MAP.get(raw,'未知')2. 工艺描述拆分
按“+”或“、”拆分工艺描述,去除空格和空元素:
defsplit_process(desc):importre parts=re.split(r'[+、]',str(desc))return[p.strip()forpinpartsifp.strip()]3. 图片文件名补全
检查图片文件名是否缺失扩展名,并尝试匹配真实图片文件列表:
importosdeffix_image_name(raw_name,image_dir):raw=str(raw_name).strip()ifnotraw:returnNoneifnotraw.endswith(('.jpg','.png','.jpeg')):raw+='.jpg'ifos.path.exists(os.path.join(image_dir,raw)):returnraw# 尝试模糊匹配forfinos.listdir(image_dir):ifraw.split('.')[0]inf:returnfreturnNone完整清洗脚本
importpandasaspdimportjsonimportreimportos# 配置INPUT_FILE='product_data.xlsx'IMAGE_DIR='./images'OUTPUT_FILE='cleaned_products.json'# 材质映射表MATERIAL_MAP={'铝合金 ADC12':'铝合金','铝合金':'铝合金','锌合金':'锌合金','铝':'铝合金','锌':'锌合金'}defnormalize_material(raw):raw=str(raw).strip()returnMATERIAL_MAP.get(raw,'未知')defsplit_process(desc):parts=re.split(r'[+、]',str(desc))return[p.strip()forpinpartsifp.strip()]deffix_image_name(raw_name,image_dir):raw=str(raw_name).strip()ifnotraw:returnNoneifnotraw.endswith(('.jpg','.png','.jpeg')):raw+='.jpg'ifos.path.exists(os.path.join(image_dir,raw)):returnrawforfinos.listdir(image_dir):ifraw.split('.')[0]inf:returnfreturnraw# 返回原始值作为兜底defclean_products():# 读取Exceldf=pd.read_excel(INPUT_FILE,engine='openpyxl')records=[]foridx,rowindf.iterrows():record={'id':idx+1,'name':str(row['产品名称']).strip(),'material':normalize_material(row.get('材质','')),'processes':split_process(row.get('工艺描述','')),'image':fix_image_name(row.get('图片文件名',''),IMAGE_DIR)}# 过滤空名称的行ifrecord['name']andrecord['name']!='nan':records.append(record)# 输出JSONwithopen(OUTPUT_FILE,'w',encoding='utf-8')asf:json.dump(records,f,ensure_ascii=False,indent=2)print(f"清洗完成,共处理{len(records)}条记录,输出至{OUTPUT_FILE}")returnrecordsif__name__=='__main__':clean_products()运行与验证
执行脚本
python clean_products.py检查输出
cleaned_products.json示例内容:
[{"id":1,"name":"汽车件铝压铸壳体","material":"铝合金","processes":["压铸成型","精密CNC加工","喷砂"],"image":"5e3232d8.jpg"},{"id":2,"name":"通讯设备散热器","material":"铝合金","processes":["压铸","机加工","阳极氧化"],"image":"5026bd1e.jpg"},{"id":3,"name":"灯具壳体","material":"锌合金","processes":["压铸","电镀"],"image":"7259de69.jpg"}]验证要点
- 字段完整性:所有记录应包含 id、name、material、processes(列表)、image 五个字段
- 材质统一性:检查 material 字段是否无“铝合金 ADC12”等未归一化值
- 工艺拆分正确性:processes 列表不应含空字符串或多余空格
- 图片匹配:确认 image 字段值对应的文件在图片目录中存在
- 异常处理:若某行产品名称为空,该行被自动跳过,不会导致脚本中断
边界情况与注意事项
- Excel 列名不匹配:若源文件列名与脚本中不一致,需先在
df.rename()中做映射 - 图片目录不存在:脚本会使用原始文件名作为兜底,建议在运行前检查路径
- 多Sheet处理:若 Excel 包含多个 Sheet,需指定
sheet_name参数 - 编码问题:Excel 中若包含特殊字符,需确认
encoding='utf-8'是否正确
总结与优化方向
本文提供了一套从 Excel 读取、字段清洗到 JSON 导出的完整流程,适用于产品资料结构化场景。核心要点:
- 材质映射:通过字典统一别名,避免数据冗余
- 工艺拆分:正则拆分多值字段,方便后续检索
- 图片匹配:补全扩展名并校验文件存在性,减少人工核对
后续可扩展的功能包括:
- 增加数据校验规则(如必填字段非空检查)
- 支持增量更新(通过 id 或时间戳去重)
- 集成数据库写入或 API 推送
参考资料
- pandas 官方文档
- openpyxl 使用指南