求SAS中SPEDIS函数的Python等效实现方法
Python实现SAS SPEDIS函数的等效功能
嘿,我之前刚好研究过怎么在Python里实现SAS的SPEDIS函数,这就给你说两种靠谱的方法!
SAS的SPEDIS本质是计算两个字符串的拼写相似度得分,返回0(完全匹配)到100(完全不相关)的数值,底层基于支持相邻字符交换的Damerau-Levenshtein编辑距离算法。
方法1:使用第三方库(推荐,简洁高效)
我们可以用python-Levenshtein库直接计算Damerau-Levenshtein距离,再转换成SPEDIS风格的得分:
首先安装依赖:
pip install python-Levenshtein
然后实现等效函数:
import Levenshtein def spedis(s1, s2): # 计算Damerau-Levenshtein编辑距离 edit_distance = Levenshtein.damerau_levenshtein(s1, s2) max_length = max(len(s1), len(s2)) if max_length == 0: return 0 # 处理空字符串情况 # 转换为0-100的得分:0=完全匹配,100=完全不相关 score = (edit_distance / max_length) * 100 return round(score, 2) # 保留两位小数,和SAS的输出风格对齐 # 测试示例 print(spedis('abc', 'abc')) # 输出 0.0,和你给的示例一致 print(spedis('abc', 'abd')) # 输出 33.33 print(spedis('abc', 'xyz')) # 输出 100.0
方法2:纯Python实现(无第三方依赖)
如果不想安装额外库,也可以自己实现Damerau-Levenshtein距离,再转换得分:
def _damerau_levenshtein(s1, s2): # 内部函数:计算Damerau-Levenshtein编辑距离 len_s1, len_s2 = len(s1), len(s2) distance_matrix = {} # 初始化边界条件 for i in range(-1, len_s1 + 1): distance_matrix[(i, -1)] = i + 1 for j in range(-1, len_s2 + 1): distance_matrix[(-1, j)] = j + 1 for i in range(len_s1): for j in range(len_s2): cost = 0 if s1[i] == s2[j] else 1 # 计算插入、删除、替换的代价 distance_matrix[(i, j)] = min( distance_matrix[(i-1, j)] + 1, # 删除 distance_matrix[(i, j-1)] + 1, # 插入 distance_matrix[(i-1, j-1)] + cost # 替换 ) # 处理相邻字符交换的情况 if i > 0 and j > 0 and s1[i] == s2[j-1] and s1[i-1] == s2[j]: distance_matrix[(i, j)] = min( distance_matrix[(i, j)], distance_matrix[(i-2, j-2)] + cost ) return distance_matrix[(len_s1-1, len_s2-1)] def spedis(s1, s2): edit_distance = _damerau_levenshtein(s1, s2) max_length = max(len(s1), len(s2)) if max_length == 0: return 0 score = (edit_distance / max_length) * 100 return round(score, 2) # 测试 print(spedis('abc', 'abc')) # 0.0 print(spedis('hello', 'hlo')) # 40.0
小提示
- SAS的
SPEDIS默认区分大小写,如果需要忽略大小写,可以在函数开头加上s1 = s1.lower(); s2 = s2.lower() - 上面的得分计算逻辑和SAS的
SPEDIS核心逻辑一致,你可以根据实际需求调整小数位数或者取整方式
内容的提问来源于stack exchange,提问作者fsong
相关产品推荐
相关产品推荐

