
本文介绍如何使用 pandas 读取 excel 中的主装配清单(含缩进层级)和在制产品清单,构建层级映射关系,自动提取每个在制装配体对应的所有子项,并输出结构化结果。
本文介绍如何使用 pandas 读取 excel 中的主装配清单(含缩进层级)和在制产品清单,构建层级映射关系,自动提取每个在制装配体对应的所有子项,并输出结构化结果。
在制造业 BOM(Bill of Materials)管理中,常需从完整主清单中快速提取特定在制(WIP)装配体及其全部子级结构。Excel 中通常以缩进(如前导点号 .)或独立层级列标识 BOM 层级。Python + pandas 可高效完成该任务,无需手动筛选。
核心思路:构建“主装配体 → 子装配体列表”映射字典
假设 Excel 文件 Production capacity and order tracking.xlsx 包含两个关键工作表:
- MDS Schedule Tracking 表:列 A 为 WIP 主装配体编号(如 ABC123465, DEW7506);
- Mfg Lead w-subs 表:列 A 为带缩进的完整 BOM 条目(如 ABC123456, .ABC124-21, ..CCC12315),列 D 为层级编号(0=顶层,1=一级子项,2=二级子项等)——优先使用此列,更鲁棒;若无层级列,则可通过统计前导点号数推断层级。
以下为完整可运行代码(含错误处理与注释):
import pandas as pd
fileName = "Production capacity and order tracking.xlsx"
# 1. 读取 WIP 主装配体列表(去空、去重)
wip_df = pd.read_excel(fileName, sheet_name="MDS Schedule Tracking", usecols="A", header=0)
wip_list = wip_df.iloc[:, 0].dropna().astype(str).str.strip().unique().tolist()
# 2. 读取主 BOM 清单(含层级信息)
# 假设列 D 为层级列(Level),列 A 为部件编号(可能含前导空格/点号)
bom_df = pd.read_excel(fileName, sheet_name="Mfg Lead w-subs", header=1, usecols="A,D")
bom_df.columns = ["item", "level"] # 显式命名列,避免歧义
bom_df["item"] = bom_df["item"].astype(str).str.strip() # 清洗空格
# 3. 构建主装配体到子项的映射字典
assembly_to_subs = {}
current_top = None
for _, row in bom_df.iterrows():
item = row["item"]
level = int(row["level"]) if pd.notna(row["level"]) else 0
if level == 0:
# 顶层项:设为当前主装配体
current_top = item
if current_top not in assembly_to_subs:
assembly_to_subs[current_top] = []
elif current_top is not None and level > 0:
# 子项:添加到当前主装配体的子项列表
assembly_to_subs[current_top].append(item)
# 4. 生成最终结果:每个 WIP 主装配体 + 其所有子装配体(含层级信息可选)
result_rows = []
for top in wip_list:
if top in assembly_to_subs:
# 添加主装配体本身(层级 0)
result_rows.append({"Assembly": top, "Sub_Assembly": top, "Level": 0})
# 添加所有子项(保持原始层级)
for sub in assembly_to_subs[top]:
# 若需还原层级,可从原始数据中提取(此处简化:子项层级 = 原始 level)
result_rows.append({"Assembly": top, "Sub_Assembly": sub, "Level": 1}) # 或保留原始 level 字段
result_df = pd.DataFrame(result_rows)
# 5. 输出到新工作表或文件
output_file = "WIP_with_subassemblies.xlsx"
with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
result_df.to_excel(writer, sheet_name="Extracted_BOM", index=False)
print(f"✅ 已成功提取 {len(wip_list)} 个 WIP 装配体及其子项,结果保存至 {output_file}")
关键注意事项:
- ✅ 层级列优先:务必确认 Mfg Lead w-subs 表中列 D 确实为准确层级(0/1/2…),这是最可靠依据;若缺失,可用 item.str.count(r'^\.*') 统计前导点号数替代,但需先 .str.strip() 防止空格干扰。
- ✅ 数据清洗不可省略:.str.strip() 处理空格、.dropna() 过滤空行、astype(str) 避免数字转科学计数法(如 123456789 变 1.23E+08)。
- ⚠️ 主装配体匹配需精确:字典键匹配为严格字符串相等,确保 WIP 列表与主清单中的顶层编号完全一致(大小写、前导零等)。
- ? 扩展建议:如需保留完整层级路径(如 ABC123456 → .ABC124-21 → ..CCC12315),可在构建字典时记录父子关系,用递归或 networkx 构建树结构。
通过此方案,您可一键将手工耗时数小时的 BOM 提取工作自动化,准确率高、可复用性强,且易于集成至日常生产报表流程中。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











