You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除SAP BOM中的虚拟物料层?附Python代码优化需求

如何移除SAP BOM中的虚拟物料层?

在SAP物料清单(BOM)中,虚拟物料常被用于关联物料关系或构建层级结构,但实际业务中往往需要移除这些虚拟层,直接展示成品到实际物料的对应关系。比如以下示例数据:

import pandas as pd

df = pd.DataFrame({
    'father': ['product1', 'product1', 'dummy1', 'dummy1', 'dummy1', 'product2', 'dummy2', 'dummy2'],
    'child': ['A', 'dummy1', 'B', 'C', 'dummy2','F', 'D', 'E']
})

其中:

  • 生产product1需要A(实际物料)和dummy1(虚拟物料)
  • dummy1包含B、C和dummy2(另一虚拟物料)
  • dummy2包含D和E
  • 最终需要得到的结果是product1直接对应A、B、C、D、E,product2对应F

你提供的原代码仅处理了单层虚拟物料的替换,未递归处理嵌套虚拟层,也未保留原始非虚拟物料条目,因此无法生成正确结果。以下是可行的解决方案:

解决方案:迭代展开虚拟物料层

通过循环迭代的方式,不断将虚拟物料的子项关联到其上层父项,直到所有虚拟层都被展开:

import pandas as pd

# 原始BOM数据
df = pd.DataFrame({
    'father': ['product1', 'product1', 'dummy1', 'dummy1', 'dummy1', 'product2', 'dummy2', 'dummy2'],
    'child': ['A', 'dummy1', 'B', 'C', 'dummy2','F', 'D', 'E']
})

# 定义所有虚拟物料的集合
dummy_items = {'dummy1', 'dummy2'}

# 第一步:保留所有非虚拟物料的基础关联
final_result = df[~df['child'].isin(dummy_items)].copy()

# 循环处理虚拟物料,直到没有可展开的虚拟层
while True:
    # 筛选出当前仍以虚拟物料为父项的记录
    dummy_parent_records = df[df['father'].isin(dummy_items)]
    if dummy_parent_records.empty:
        break
    
    # 建立虚拟物料到其上层父项的映射
    dummy_to_top_parent = df[df['child'].isin(dummy_parent_records['father'].unique())] \
                          .rename(columns={'father': 'top_father', 'child': 'dummy'})
    
    # 将虚拟物料的子项关联到上层父项,生成新的关联记录
    expanded_records = pd.merge(dummy_parent_records, dummy_to_top_parent, 
                               left_on='father', right_on='dummy')[['top_father', 'child']] \
                               .rename(columns={'top_father': 'father'})
    
    # 将新记录加入结果集
    final_result = pd.concat([final_result, expanded_records], ignore_index=True)
    
    # 移除已处理的虚拟父项记录,避免重复处理
    df = df[~df['father'].isin(dummy_parent_records['father'].unique())]

# 最后过滤掉残留的虚拟物料子项,去重并排序
final_result = final_result[~final_result['child'].isin(dummy_items)] \
               .drop_duplicates() \
               .sort_values(by=['father', 'child']) \
               .reset_index(drop=True)

print(final_result)

代码逻辑说明

  1. 基础条目保留:先提取所有直接关联实际物料的记录(如product1->A、product2->F)。
  2. 迭代展开虚拟层:每次找到以虚拟物料为父项的记录,通过映射找到虚拟物料的上层父项,将子项直接关联到上层父项,生成新记录。
  3. 终止条件:当没有以虚拟物料为父项的记录时,停止循环。
  4. 结果整理:过滤掉残留的虚拟物料,去重后排序,得到目标格式的数据。

运行上述代码后,输出结果将与你期望的df_desired完全一致。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 16:37:53