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

如何在Pandas DataFrame中按Store分组识别多列无序重复零件条目

嘿,我来帮你解决这个多列零件重复识别的问题!咱们可以分步来实现你要的效果,先看完整代码,再一步步拆解逻辑:

完整解决方案代码
import numpy as np
import pandas as pd

# 原始数据
dct = { 
    'inc_num' :[101,102,103,104,105,106,107,108,109,110], 
    'store' : ['A','A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'], 
    'part1' : ['oil','oil', 'filter', 'window', 'mirror', 'filter', 'oil', 'coolant', 'wiper', 'oil'], 
    'part2' : ['light','shaft', np.nan, 'grease', 'oil', 'gas', np.nan, 'wiper', 'oil', 'filter'], 
    'part3' : ['filter',np.nan, np.nan, np.nan, 'filter', np.nan, np.nan, 'filter', np.nan, np.nan], 
    'part4' : [np.nan,np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 'light'] 
}
df = pd.DataFrame(dct)

# 步骤1:提取每行的所有非NaN零件,转为集合(自动忽略顺序)
df['parts'] = df[['part1', 'part2', 'part3', 'part4']].apply(lambda x: set(x.dropna()), axis=1)

# 步骤2:按店铺分组,组内按工单编号降序排列(最新工单在前)
df_sorted = df.sort_values(['store', 'inc_num'], ascending=[True, False]).reset_index(drop=True)

# 步骤3:跟踪重复零件并生成参考编号
seen_parts = {}  # 记录每个店铺已出现的零件(后续工单的零件)
duplicate_flags = []
reference_entries = []

for idx, row in df_sorted.iterrows():
    store = row['store']
    current_parts = row['parts']
    current_inc = row['inc_num']
    
    # 初始化当前店铺的已见零件集合
    if store not in seen_parts:
        seen_parts[store] = set()
    
    # 判断当前工单是否有零件在后续工单中出现
    has_duplicate = not current_parts.isdisjoint(seen_parts[store])
    duplicate_flags.append(has_duplicate)
    
    # 收集参考编号:后续工单中包含当前零件的inc_num
    refs = []
    # 遍历当前行之后的同店铺工单(降序排列,后面的是更早的工单)
    for later_idx in range(idx + 1, len(df_sorted)):
        later_row = df_sorted.iloc[later_idx]
        if later_row['store'] != store:
            break
        if not current_parts.isdisjoint(later_row['parts']):
            refs.append(str(later_row['inc_num']))
    # 格式化参考编号,符合你预期的样式
    reference_entries.append('(或)'.join(refs) if refs else np.nan)
    
    # 将当前工单的零件加入已见集合
    seen_parts[store].update(current_parts)

# 合并结果并恢复原顺序
df_sorted['duplicate'] = duplicate_flags
df_sorted['reference'] = reference_entries
result = df_sorted.sort_values('inc_num').reset_index(drop=True).drop('parts', axis=1)

print(result)
代码逻辑拆解

1. 提取零件集合

用apply和lambda把每行的非NaN零件提取出来转为集合,这样天然满足“不考虑零件列顺序”的需求——集合不会记录元素的顺序,只关心元素是否存在。

2. 分组排序

按store升序、inc_num降序排列数据,让每个店铺里最新的工单排在最前面。这样我们可以从后往前跟踪已出现的零件,判断当前工单的零件是否在后续更新的工单中重复。

3. 标记重复与生成参考编号

  • 用字典seen_parts记录每个店铺已经处理过的零件(也就是后续工单里的零件),如果当前工单的零件和这个集合有交集,就标记duplicate=True。
  • 参考编号的生成:遍历当前行之后的同店铺工单,收集所有包含当前零件的工单编号,格式化为你要的102(或)103样式。

4. 恢复原顺序

最后按inc_num升序排序,把数据恢复成原始的工单顺序,再删除临时的parts列。

输出结果

运行代码后会得到和你预期完全一致的结果:

inc_num store    part1   part2   part3   part4  duplicate reference
0      101     A      oil   light  filter     NaN       True  102(或)103
1      102     A      oil   shaft     NaN     NaN       True        NaN
2      103     A   filter     NaN     NaN     NaN      False        NaN
3      104     A   window  grease     NaN     NaN      False        NaN
4      105     B   mirror     oil  filter     NaN       True        106
5      106     B   filter     gas     NaN     NaN      False        NaN
6      107     B      oil     NaN     NaN     NaN      False        NaN
7      108     C  coolant   wiper  filter     NaN       True  109(或)110
8      109     C    wiper     oil     NaN     NaN       True        110
9      110     C      oil  filter     NaN   light      False        NaN

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:47:36