列表性能中的Python模糊匹配字符串
Posted
技术标签:
【中文标题】列表性能中的Python模糊匹配字符串【英文标题】:Python Fuzzy matching strings in list performance 【发布时间】:2019-09-26 04:36:15 【问题描述】:我正在检查 4 个相同的数据框列中是否有相似的结果(模糊匹配),我有以下代码作为示例。当我将它应用到真正的 40.000 行 x 4 列数据集时,它会一直在 eternum 中运行。问题是代码太慢了。例如,如果我将数据集限制为 10 个用户,计算需要 8 分钟,而计算需要 20、19 分钟。有什么我想念的吗?我不知道为什么要花那么长时间。我希望在 2 小时或更短的时间内获得所有结果。任何提示或帮助将不胜感激。
from fuzzywuzzy import process
dataframecolumn = ["apple","tb"]
compare = ["adfad","apple","asple","tab"]
Ratios = [process.extract(x,compare) for x in dataframecolumn]
result = list()
for ratio in Ratios:
for match in ratio:
if match[1] != 100:
result.append(match)
break
print (result)
输出: [('asple', 80), ('tab', 80)]
【问题讨论】:
尝试自己实现 Levenshtein Distance 并查看执行时间之间的差异。也许您正在使用的库在时间效率方面存在问题 @CristianIacob 我正在使用fuzzywuzzy 我过去已经解决了这个问题,但在这里需要更多信息。您是否正在使用比率或部分比率或两者来寻找字符串相似性?您是否使用提取功能只是为了加快处理速度? @Atendra 使用比率(不是部分),我使用提取函数来加快速度,是的。只要我能达到预期的结果,我对任何新代码都持开放态度。 我希望下面的答案能解决你的问题。 【参考方案1】:通过编写矢量化操作和避免循环来显着提高速度
导入必要的包
from fuzzywuzzy import fuzz
import pandas as pd
import numpy as np
从第一个列表创建数据框
dataframecolumn = pd.DataFrame(["apple","tb"])
dataframecolumn.columns = ['Match']
从第二个列表创建数据框
compare = pd.DataFrame(["adfad","apple","asple","tab"])
compare.columns = ['compare']
Merge - 通过引入键(自连接)的笛卡尔积
dataframecolumn['Key'] = 1
compare['Key'] = 1
combined_dataframe = dataframecolumn.merge(compare,on="Key",how="left")
combined_dataframe = combined_dataframe[~(combined_dataframe.Match==combined_dataframe.compare)]
矢量化
def partial_match(x,y):
return(fuzz.ratio(x,y))
partial_match_vector = np.vectorize(partial_match)
使用矢量化并通过将阈值设置为分数来获得所需的结果
combined_dataframe['score']=partial_match_vector(combined_dataframe['Match'],combined_dataframe['compare'])
combined_dataframe = combined_dataframe[combined_dataframe.score>=80]
结果
+--------+-----+--------+------+
| Match | Key | compare | score
+--------+-----+--------+------+
| apple | 1 | asple | 80
| tb | 1 | tab | 80
+--------+-----+--------+------+
【讨论】:
执行你的脚本,结果和你给的不一样。它返回Match Key compare score 1 apple 1 apple 100
忘记包含否定。现在更正了。试着让我知道。它现在提供相同的输出。
这不适用于非常大的数据集。我在一列中有 50,000 个字符串,可以与另一列 400,000 个字符串进行比较。将这些与您的代码合并时有一个Memoryerror
Merge - Cartesian product by introducing key(self join)
@SCool 由于数据比较适中,组合的数量会显着增加。您可以通过一些过滤器或逻辑来减少这些组合吗?您真的需要将所有 50 K 字符串与 4 个 Lac 字符串匹配吗?如果是,您将需要更多 RAM。
非常有用,谢谢!补充一下,我必须对我的数据尝试不同的模糊方法,token_set_ratio
效果最好。 towardsdatascience.com/…以上是关于列表性能中的Python模糊匹配字符串的主要内容,如果未能解决你的问题,请参考以下文章
dev 中 字符串转中文拼音缩写,对grid列表进行模糊匹配,grid获取焦点行,gridlookupedit控件用拼音模糊匹配下拉选项