说明
假设场景:有一批表格文件,有两列文本需要比对结果是否一致。
简单考虑以下情况:
- 1 如果文本本身就比较短,那么出现差异时就很难说对错
- 2 如果文字本身较长,可以通过编辑距离检查两个文本的差异
- 3 有可能文本虽然编辑距离大,但是意思接近,这时候简单的使用结巴分词比较词组
需求:原始文件是一批csv, 里面已经对两列数据进行了判定,字段结果为“无数据”、“不一致”,现在需要人对不一致的部分进行详细比对。(原程序只是比较了值是否一致,现在需要准确的确认。例如,“上海市” 不等于 “上海”,但是其实本来是一回事)
程序的作用是过滤出需要比对的记录,并给出相似度的量化参考。
处理
获取数据。原始文件使用csv保存存在问题,csv以逗号作为分隔符而数据本身存在逗号,这样导致了分列的失败。因此转为直接去取行文本直接处理。
import DataManipulation as dm
import pandas as pd
import os
data_folder = './人为对比优化/'
file_list = os.listdir('./人为对比优化/')
data_dict = {}
line_index_dict = {}
meta_dict = {}
for the_file in file_list:
data_dict[the_file] = []
line_index_dict[the_file] = []
meta_dict[the_file] = {}
meta_dict[the_file]['无数据'] = 0
meta_dict[the_file]['不一致'] = 0
meta_dict[the_file]['其他'] = 0
with open(data_folder + the_file) as f:
lines = f.readlines()
for i,line in enumerate(lines):
if '无数据' in line:
meta_dict[the_file]['无数据'] += 1
elif '不一致' in line:
meta_dict[the_file]['不一致'] += 1
data_dict[the_file].append(line)
line_index_dict[the_file].append(i)
else:
meta_dict[the_file]['其他'] += 1
# 基本数据比对输出
base_compare = dm.flat_dict(meta_dict)
base_compare_df = dm.flat_dict2df(base_compare)
base_compare_df.to_excel('基本比对信息.xlsx')
基本结果如下:
接下来析取关键的比对字段,原字段的保存还是有一定规范的...,a平台:str1,测试数据:str2
# 析取不一致的字段对比
dif_dict = {}
for k in data_dict.keys():
dif_dict[k] = []
for i,the_line in enumerate(data_dict[k]):
line_index = line_index_dict[k][i]
the_line = the_line.replace('\n', '')
pos1 = the_line.find(',a平台:')
pos2 = the_line.find(',测试数据:')
str1 = the_line[pos1+6:pos2].strip()
str2 = the_line[pos2+6:].strip()
str1_len = len(str1)
str2_len = len(str2)
is_len = str(1 if str1_len else 0) + str(1 if str2_len else 0)
# 如果有长度才进行比较
# 1 编辑距离
import Levenshtein
if str1_len and str2_len:
ldis = Levenshtein.distance(str1, str2)
lsimi = ldis / max(str1_len, str2_len)
else:
ldis = -1
lsimi= -1
# 2 结巴分词
import jieba
if str1_len and str2_len:
set1 = set(jieba.cut(str1))
set2 = set(jieba.cut(str2))
uset = set1|set2
iset = set1& set2
uset_len = len(uset)
iset_len = len(iset)
jsimi = iset_len / uset_len
else:
jsimi = -1
uset_len =-1
iset_len =-1
tem_dict = {}
tem_dict['line_index'] = line_index
tem_dict['str1_a平台'] = str1
tem_dict['str2_测试'] = str2
tem_dict['str1_len'] = str1_len
tem_dict['str2_len'] = str2_len
tem_dict['is_len'] = is_len
tem_dict['ldis'] = ldis
tem_dict['lsimi_编辑距离相似度'] = 1 - lsimi if lsimi >0 else lsimi
tem_dict['并集词组长度'] = uset_len
tem_dict['交集词组长度'] = iset_len
tem_dict['词组相似度'] = jsimi
dif_dict[k].append(tem_dict)
res_df_list = []
for k in dif_dict.keys():
tem_df = pd.DataFrame(dif_dict[k])
tem_df['file'] = k
res_df_list.append(tem_df)
dif_res_df = pd.concat(res_df_list, ignore_index=True)
dif_res_df.to_excel('对比细节.xlsx')
以下是部分比对细节,例如 “陕西省西咸新区市场监督管理局秦汉新城分局”和“西咸新区工商行政管理局秦汉新城分局”数据肯定不一致,但是编辑距离差距并没有那么大,分割成词组也有一定的相似性。
编辑距离和结巴分词的介绍可以参考以下文章。