python - 寻找一种更快的模糊字符串匹配方法
问题描述
我在python中使用fuzzywuzzy进行模糊字符串匹配。我在名为 HKCP_list 的列表中有一组名称,我将其与 pandas 列迭代匹配以获得最佳匹配。下面给出的是它的代码
import fuzzywuzzy
from fuzzywuzzy import fuzz,process
def search_func(row):
chk = process.extract(row,HKCP_list,scorer=fuzz_token_sort_ratio)[0]
return chk
wc_df['match']=wc_df['concat_name'].map(search_func)
wc_df 数据框包含需要与列表 HKCP_list 中的每个名称匹配的列“concat_name”。上面的代码运行了大约 2 个小时,列表中有 6K 个名称,“concat_name”列中有 11K 个名称。
我必须在另一个数据集上重新运行它,其中列表中有 89K 名称,列中有 120K 名称。为了加快这个过程,我在 Stackoverflow 上的以下问题中得到了一个想法
在上述答案的其中一条评论中,建议比较具有相同第一个字母的名称。我要比较的“concat_name”列是通过连接数据框中的“first_name”和“last_name”列获得的派生列。因此,我使用以下函数来匹配第一个字母(因为这是我正在考虑的令牌排序分数,所以我将 first_name 和 last_name 的第一个字母与列表中的元素进行比较)。下面给出的是代码:
wc_df['first_name_1stletter'] = wc_df['first_name'].str[0]
wc_df['last_name_1stletter'] = wc_df['last_name'].str[0]
import time
start_time=time.time()
def match_func(row):
CP_subset=[x for x in HKCP_list if x[0]==row['first_name_1stletter'] or x[0]==row['last_name_1stletter']]
return CP_subset
wc_df['list_to_match']=wc_df.apply(match_func,axis=1)
end_time=time.time()
print(end_time-start_time)
上述步骤使用 6K X 11K 数据耗时 1600 秒。'list_to_match' 列包含要为每个 concat_name 比较的名称列表。现在在这里我必须再次获取 list_to_match 元素并传递列表中的各个元素,并使用 process.extract 方法进行模糊字符串匹配。在与上述相同的步骤中是否有更优雅和更快的方法?
PS:编辑此内容以添加有关列表和数据框列外观的示例。
HKCp_list=['jeff bezs','michael blomberg','bill gtes','tim coook','elon musk']
concat_name=['jeff bezos','michael bloomberg','bill gates','tim cook','elon musk','donald trump','kim jong un', 'narendra modi','michael phelps']
first_name=['jeff','michael','bill','tim','elon','donald','kim','narendra','michael']
last_name=['bezos','bloomberg','gates','cook','musk','trump','jong un', 'modi','phelps']
import pandas as pd
df=pd.DataFrame({'first_name':first_name,'last_name':last_name,'concat_name':concat_name})
df 中“concat_name”的每一行都必须与 HKcp_list 的元素进行比较。
PS:今天编辑以反映我昨天错过的第二段代码中的“:”和行
问候,尼尔维克
解决方案
你可以试试我在另一个答案中写的这个函数,不是 100% 确定它在速度方面的表现,你可以自己试试:
from fuzzywuzzy import fuzz
from fuzzywuzzy import process
# Make dataframe out of list
HKCp = pd.DataFrame({'names':HKCp_list})
# Use fuzzy_merge function
fuzzy_merge(df, HKCp, 'concat_name', 'names')
输出
first_name last_name concat_name matches
0 jeff bezos jeff bezos jeff bezs
1 michael bloomberg michael bloomberg michael blomberg
2 bill gates bill gates bill gtes
3 tim cook tim cook tim coook
4 elon musk elon musk elon musk
5 donald trump donald trump
6 kim jong un kim jong un
7 narendra modi narendra modi
8 michael phelps michael phelps
请注意,您可以使用treshold
参数来获得不太精确的匹配
推荐阅读
- api - 使用 MS Graph API 是否可以搜索组日历并返回会议时间,即使只有一个组成员可用?
- android - 如何使用socket.io将android kotlin连接到sails js
- kubernetes - 在 kubernetes 中使用 service Mesh 时还需要 CNI 吗?
- javascript - 如何使用 JavaScript 选择 div 元素并更改背景颜色?
- java - Java 泛型:您可以在类构造函数中实例化类型参数的对象吗?
- java - Java Springboot Security - 处理依赖注入
- reactjs - 尝试导入错误:“shouldUseActivityState”未从“react-native-screens”导出
- html - Bootstrap 4 嵌入带有控件的响应式视频
- sql-server - 相同值的行号
- visual-studio-2019 - Visual Studio 2019 展示实现