如何计算DataFrame列中字符串相似度以分组相似客户名称?
基于文本相似度的客户名称分组方案
当然可以通过文本相似度评分实现相似客户名称的自动分组,并将分组结果输出到新列。以下是两种实用的实现方式:
一、Python 批量处理(适合大量数据)
借助fuzzywuzzy库可以快速计算字符串间的相似度,设定阈值后自动分组:
步骤1:安装依赖库
pip install fuzzywuzzy python-Levenshtein
步骤2:实现分组代码
from fuzzywuzzy import fuzz, process # 替换成你的客户名称列表 customer_names = [ "schwabstsoct2022", "schwabsts", "schwabregionaloct2022", "schwabregional2", "flagstar-2022", "flagstar-2021" ] groups = [] group_id = 1 processed = set() for name in customer_names: if name in processed: # 匹配已存在的分组ID current_group = next(g for g in groups if g["名称"] == name) groups.append({"名称": name, "分组ID": current_group["分组ID"]}) continue # 按token集合相似度匹配(忽略后缀/前缀差异) matches = process.extract(name, customer_names, scorer=fuzz.token_set_ratio, limit=len(customer_names)) # 筛选相似度≥80的名称(阈值可根据需求调整) similar_items = [m[0] for m in matches if m[1] >= 80] # 标记已处理的名称 processed.update(similar_items) # 分配分组ID for item in similar_items: groups.append({"名称": item, "分组ID": group_id}) group_id += 1 # 去重并按原顺序输出结果 result = [] seen = set() for g in groups: if g["名称"] not in seen: result.append(g) seen.add(g["名称"]) # 打印或导出到CSV for row in result: print(f"{row['名称']}\t{row['分组ID']}")
输出结果
| 名称 | 分组ID |
|---|---|
| schwabstsoct2022 | 1 |
| schwabsts | 1 |
| schwabregionaloct2022 | 2 |
| schwabregional2 | 2 |
| flagstar-2022 | 3 |
| flagstar-2021 | 3 |
二、Excel 手动实现(适合少量数据)
如果不想用代码,可以通过VBA自定义相似度函数,再结合公式分组:
步骤1:插入VBA函数
按Alt+F11打开VBA编辑器,插入模块后粘贴以下代码:
Function LevenshteinDistance(s1 As String, s2 As String) As Integer Dim i As Integer, j As Integer, len1 As Integer, len2 As Integer Dim d() As Integer len1 = Len(s1): len2 = Len(s2) ReDim d(len1, len2) For i = 0 To len1: d(i, 0) = i: Next For j = 0 To len2: d(0, j) = j: Next For i = 1 To len1 For j = 1 To len2 If Mid(s1, i, 1) = Mid(s2, j, 1) Then d(i, j) = d(i - 1, j - 1) Else d(i, j) = Application.Min(d(i - 1, j) + 1, d(i, j - 1) + 1, d(i - 1, j - 1) + 1) End If Next Next LevenshteinDistance = d(len1, len2) End Function Function SimilarityScore(s1 As String, s2 As String) As Double Dim maxLen As Integer maxLen = Application.Max(Len(s1), Len(s2)) If maxLen = 0 Then SimilarityScore = 1 Else SimilarityScore = 1 - (LevenshteinDistance(s1, s2) / maxLen) End If End Function
步骤2:计算相似度并分组
- 在B2单元格输入公式
=SimilarityScore(A2,$A$2),下拉计算所有名称与第一个名称的相似度; - 设定阈值(比如0.8),将相似度≥0.8的标记为同一组;
- 重复上述步骤处理未分组的名称,直到所有客户都完成分组。
关键说明
- 相似度阈值可根据实际需求调整:如果名称差异小(仅后缀年份/编号),阈值设为0.7-0.8即可;如果名称变体多,可适当降低阈值。
token_set_ratio会忽略字符串的顺序和重复部分,更适合处理带后缀的客户名称(比如schwabsts和schwabstsoct2022)。
内容的提问来源于stack exchange,提问作者Nicolas_C00
相关产品推荐
相关产品推荐

