我正在尝试进行字符串匹配,并在python中使用模糊wuzzy引入匹配ID。我的数据集非常庞大,数据集1 = 180万条记录,数据集2 = 160万条记录。
到目前为止我尝试了什么,
首先我尝试在python中使用record linkage
包,遗憾的是它在构建multi index
时内存不足,所以我移植到具有良好机器功能的AWS并成功构建它,但是当我试图对它进行比较,它会永远运行,我同意它的比较数量。
然后,我尝试与fuzzy wuzzy
进行字符串匹配,并使用dask
包并行处理该进程。并在样本数据上执行它。它工作正常,但我知道这个过程仍然需要时间,因为搜索空间很宽。我正在寻找一种方法来为这段代码添加阻塞或索引。
test = pd.DataFrame({'Address1':['123 Cheese Way','234 Cookie Place','345 Pizza Drive','456 Pretzel Junction'],'city':['X','U','X','U']})
test2 = pd.DataFrame({'Address1':['123 chese wy','234 kookie Pl','345 Pizzza DR','456 Pretzel Junktion'],'city':['X','U','Z','Y'] , 'ID' : ['1','3','4','8']})
在这里,我想在test.Address1
中查找test2.Address1
并带来ID
。
def fuzzy_score(str1, str2):
return fuzz.token_set_ratio(str1, str2)
def helper(orig_string, slave_df):
slave_df['score'] = slave_df.Address1.apply(lambda x: fuzzy_score(x,orig_string))
#return my_value corresponding to the highest score
return slave_df.ix[slave_df.score.idxmax(),'ID']
dmaster = dd.from_pandas(test, npartitions=24)
dmaster = dmaster.assign(ID_there=dmaster.Address1.apply(lambda x: helper(x, test2)))
dmaster.compute(get=dask.multiprocessing.get)
这很好用,但我不确定如何通过限制同一城市的搜索空间来对其进行索引。
可以说,我正在基于原始字符串的城市创建城市字段和子集的索引,并将该城市传递给辅助函数,
# sort the dataframe
test2.sort_values(by=['city'], inplace=True)
# set the index to be this and don't drop
test2.set_index(keys=['city'], drop=False,inplace=True)
我不知道该怎么办?请指教。提前致谢。
答案 0 :(得分:1)
我更喜欢使用fuzzywuzzy.process.extractOne
。这将字符串与可迭代的字符串进行比较。
def extract_one(col, other):
# need this for dask later
other = other.compute() if hasattr(other, 'compute') else other
return pd.DataFrame([process.extractOne(x, other) for x in col],
columns=['Address1', 'score', 'idx'],
index=col.index)
extract_one(test.Address1, test2.Address1)
Address1 score idx
0 123 chese wy 92 0
1 234 kookie Pl 83 1
2 345 Pizzza DR 86 2
3 456 Pretzel Junktion 95 3
idx
是传递给other
的{{1}}与最近匹配的索引。我建议有一个有意义的索引,以便以后更容易地加入结果。
关于第二个问题,关于过滤到城市,我会使用groupby并应用
extract_one
与dask的唯一区别是需要为apply:
指定gr1 = test.groupby('city')
gr2 = test2.groupby("city")
gr1.apply(lambda x: extract_one(x.Address1,
gr2.get_group(x.name).Address1))
Address1 score idx
0 123 chese wy 92 0
1 234 kookie Pl 83 1
2 345 Pizzza DR 86 2
3 456 Pretzel Junktion 95 3
meta
这是一个笔记本:https://gist.github.com/a932b3591346b898d6816a5efc2bc5ad
我很想知道表演是怎样的。我假设在模糊wuzzy中完成的实际字符串比较将占用大部分时间,但我很想知道在pandas和dask中花费了多少开销。确保你有计算Levenshtein距离的C扩展。
答案 1 :(得分:0)
我一次遇到相同的问题。整个过程将花费很长时间,即使您将使用多重处理,也并不是真的很快。导致速度降低的主要问题是模糊匹配,因为处理非常繁琐且需要大量时间。
在我看来,更有效的选择是使用嵌入又一袋的单词并在其上应用ML方法。您将使用数值向量的事实使整个过程更快!