本帖最后由 dommy 于 2024-8-1 14:07 编辑
因工作需要,对原有客商开户信息匹配上联行号(已有一份行名+联行号基础数据),但即有客商开户信息录入五花八门,通过Excel的VLOOKUP精确处理只得到很小一部分有用信息,但其模糊匹配功能处理结果差强人意,于是用Python做了一个相似度匹配。
运行后的结果如下图(当前截图以工行为例,因数据量大,“工行”二字已删除以提高效率):
处理后的结果
源代码如下:
import pandas as pd
from fuzzywuzzy import process
#读取Excel文件
file_path = 'C:\\Users\\mwm\\Documents\\gonghang.xlsx' # 替换为你的Excel文件路径
df = pd.read_excel(file_path)
#假设你的原文本列名为'SourceText',目标文本列名为'TargetText'
source_column = 'SourceText' # 替换为你的原文本列名
target_column = 'TargetText' # 替换为你的目标文本列名
closest_match_column = 'ClosestMatch' # 新列名,用于存储最相似的文本
similarity_column = 'Similarity' # 新列名,用于存储相似度得分
#计算相似度,并找到最相似的文本
def find_closest_matches(source_texts, target_texts):
closest_matches = []
similarities = []
i = 0
for source in source_texts:
closest = process.extractOne(source, target_texts)
closest_matches.append(closest[0])
similarities.append(closest[1])
i = i + 1
if i % 100 == 0:
print("已处理 %d 行数据" % i)
return closest_matches, similarities
#过滤空值和空白值
non_empty_source_texts = [text for text in df[source_column] if pd.notna(text) and text.strip()]
non_empty_target_texts = df[target_column].tolist() # 假设目标列也需要处理,但通常我们保留所有目标文本
#应用函数,并创建新列
closest_matches, similarities = find_closest_matches(non_empty_source_texts, non_empty_target_texts)
#创建一个新的DataFrame来存储匹配结果
results_df = pd.DataFrame({
closest_match_column: closest_matches,
similarity_column: similarities
})
#将结果DataFrame与原始DataFrame合并,只针对非空源文本
#使用一个临时列来帮助合并,这里我们使用源文本的索引
df['temp_index'] = df.index
results_df['temp_index'] = range(len(non_empty_source_texts))
merged_df = pd.merge(df, results_df, on='temp_index', how='left')
#删除临时列
merged_df.drop(columns=['temp_index'], inplace=True)
#将结果写回Excel文件
merged_df.to_excel(file_path, index=False)
print("相似度匹配完成,并已写入原文件。")
若有更好的处理方式,请大佬们赐教! |