大规模零售租户名称字符串清洗代码运行效率优化求助
零售租户名称模糊匹配清洗代码优化建议
当前代码的性能瓶颈主要来自三点:一是双层遍历的O(n²)时间复杂度,租户数量增长后匹配次数指数级上升;二是频繁查询、拼接DataFrame带来的额外开销;三是模糊匹配库的底层计算效率偏低。可按以下优先级优化:
1. 优先替换模糊匹配底层库,零代码改动提效10~100倍
你当前用的fuzzywuzzy如果没有安装C实现的python-Levenshtein依赖,默认是纯Python计算编辑距离,速度极慢。可直接替换为RapidFuzz库,完全兼容fuzzywuzzy的API,底层为C++实现,匹配速度提升非常明显,仅需修改导入语句:
# 替换原有 from fuzzywuzzy import fuzz from rapidfuzz import fuzz
WRatio、UQRatio的计算逻辑和返回值和fuzzywuzzy完全一致,不需要调整后续判断逻辑。
2. 砍掉90%以上无效匹配,降低时间复杂度
原有逻辑要求所有租户两两比对,1000条租户就需要近50万次匹配,2000条就涨到200万次,可通过分桶逻辑大幅减少匹配次数:
- 先对租户名做标准化预处理:统一转大写、删除所有特殊符号(单引号、空格、横杠、&等)、去除首尾空白
- 按预处理后的名称首字母、或2-gram(前两个字符)分桶,仅同一个桶内的租户才需要做模糊匹配,比如所有M开头的租户在一个桶,不需要和A开头的Abercrombie、G开头的GAP做比对
3. 替换低效的DataFrame操作,用字典做映射缓存
你当前每次内层循环都查询整个df_lookup表、每次迭代都拼接DataFrame,这部分开销甚至比匹配计算本身还高。可直接用Python字典做标准化名称的映射缓存,查询复杂度为O(1),同时不需要存储所有迭代的中间过程数据:
# 按规则排序后取租户列表 sorted_tenants = df.sort_values(by=['Num_Of_Locations','Total_GLA'], ascending=False).Tenant_Name.to_list() # 缓存映射:key=原始租户名,value=标准化后名称 clean_map = {name:name for name in sorted_tenants} for i, name1 in enumerate(sorted_tenants): # 已经被映射为更高优先级名称的,直接跳过比对 if clean_map[name1] != name1: continue # 仅和后面未处理的租户比对 for name2 in sorted_tenants[i+1:]: # 已经被映射过的直接跳过 if clean_map[name2] != name2: continue # 先算快的匹配分,低于阈值直接跳过第二个分数计算 s2 = fuzz.UQRatio(name1, name2) if s2 < 70: continue s1 = fuzz.WRatio(name1, name2) if s1 <=0: continue harmonic_value = 2*s1*s2/(s1+s2) if harmonic_value > 80: clean_map[name2] = name1 # 最后转成DataFrame即可 df_mapping = pd.DataFrame(clean_map.items(), columns=['原始租户名', '标准化租户名'])
4. 额外优化点
- 可提前对租户名去重,完全重复的名称不需要重复匹配,仅保留唯一值处理后再映射回原数据
- 如果租户量过万,可进一步用向量检索方案:把租户名转成n-gram向量,用faiss做近似近邻检索,直接返回相似度前N的候选,再做精确匹配,时间复杂度可降到O(n log n)
内容的提问来源于stack exchange,提问作者user14838970
相关产品推荐
相关产品推荐

