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

如何在Python中对DataFrame相邻行零件编号执行Sequence Matcher匹配并提取系列?

解决方案

方案可行性说明

你的方案完全可行,必须先将零件编号转为字符串类型——因为difflib.SequenceMatcher仅处理字符串,Excel导入的列如果是数值型(比如纯数字编号)会导致匹配错误。

具体实现流程

1. 数据预处理:转换为字符串

先确保零件编号列是字符串格式:

import pandas as pd

# 假设已从Excel导入DataFrame为df
df['MANUFACTURER PART NUMBER 1'] = df['MANUFACTURER PART NUMBER 1'].astype(str)

2. 计算相邻行相似度并添加分数列

利用pandas.shift()获取下一行的编号,结合difflib.SequenceMatcher.ratio()计算相似度,最后一行留空:

from difflib import SequenceMatcher

def get_similarity(current, next_part):
    if pd.isna(next_part):
        return None
    return SequenceMatcher(None, current, next_part).ratio()

# 生成下一行编号列
df['next_part'] = df['MANUFACTURER PART NUMBER 1'].shift(-1)
# 计算相似度分数
df['Similarity Score'] = df.apply(lambda row: get_similarity(row['MANUFACTURER PART NUMBER 1'], row['next_part']), axis=1)
# 删除临时列
df.drop('next_part', axis=1, inplace=True)

3. 从高相似度编号提取零件系列

步骤3.1:将高相似度编号分组

设定相似度阈值(比如0.8,可根据实际调整),把相邻且相似度达标的编号归为同一组:

similarity_threshold = 0.8
# 当相似度低于阈值时,组ID递增,实现分组
df['group_id'] = (df['Similarity Score'] < similarity_threshold).cumsum()

步骤3.2:提取每组的公共零件系列

针对每组编号,提取最频繁的公共字符序列,或结合前缀/后缀生成带可变标记的系列名(如RK73H2ATTDxxxxF):

from collections import Counter

def extract_common_series(part_numbers):
    # 收集所有两两编号的长公共子串(长度≥3)
    common_substrings = []
    min_len = min(len(p) for p in part_numbers)
    if min_len < 3:
        return part_numbers[0]
    
    for i in range(len(part_numbers)):
        for j in range(i+1, len(part_numbers)):
            matcher = SequenceMatcher(None, part_numbers[i], part_numbers[j])
            longest_match = matcher.find_longest_match(0, len(part_numbers[i]), 0, len(part_numbers[j]))
            if longest_match.size >= 3:
                common_substrings.append(part_numbers[i][longest_match.a:longest_match.a+longest_match.size])
    
    if not common_substrings:
        return part_numbers[0]
    
    # 取出现最频繁的公共子串
    most_freq_sub = Counter(common_substrings).most_common(1)[0][0]
    
    # 提取公共前缀和后缀,中间用xxxx替代可变部分
    prefix = ""
    for idx in range(min_len):
        chars = [p[idx] for p in part_numbers]
        if len(set(chars)) == 1:
            prefix += chars[0]
        else:
            break
    
    suffix = ""
    for idx in range(1, min_len+1):
        chars = [p[-idx] for p in part_numbers]
        if len(set(chars)) == 1:
            suffix = chars[0] + suffix
        else:
            break
    
    if prefix or suffix:
        return f"{prefix}xxxx{suffix}"
    else:
        return most_freq_sub

# 为每行添加对应的零件系列
df['Part Series'] = df.groupby('group_id')['MANUFACTURER PART NUMBER 1'].transform(lambda x: extract_common_series(x.tolist()))

优化建议

  • 相似度阈值可根据编号的实际差异调整(比如精密零件编号相似度阈值设为0.9,通用零件设为0.7)
  • 如果编号有固定格式(如前缀+数字序列+后缀),可以用正则表达式直接提取固定部分,效率比两两匹配更高
  • 若数据量极大,可考虑用向量化操作替代apply提升速度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 05:54:38