【发布时间】:2016-11-25 14:10:47
【问题描述】:
我有带有 cli id 和来源的 DataFrame A (df_cam):
cli id | origin
------------------------------------
123 | 1234 M-MKT XYZklm 05/2016
和带有快捷方式和活动的 DataFrame B (df_dict)
shortcut | campaign
------------------------------------
M-MKT | Mobile Marketing Outbound
我知道,例如来自 1234 M-MKT XYZklm 05/2016 的客户实际上来自活动 Mobile Marketing Outbound,因为它包含关键字 M-MKT。
请注意,快捷方式是一个通用关键字,取决于算法应决定的内容。原点也可以是M-Marketing、MMKT 或Mob-MKT。我首先通过分析所有来源手动创建了快捷方式列表。我还使用正则表达式在将origin 提取到程序之前对其进行清理。
我想通过快捷方式将客户来源与广告系列匹配并附加分数以查看差异。如下图:
cli id | shortcut | origin | campaign | Score
---------------------------------------------------------------------------------
123 | M-MKT | 1234 M-MKT XYZklm 05/2016 | Mobile Marketing Outbound | 0.93
下面是我的程序,它可以运行,但是真的很慢。 DataFrame A 有 ~400.000 行,另一个 DataFrame B 有 ~40 行。
有什么方法可以让它更快吗?
from fuzzywuzzy import fuzz
list_values = df_dict['Shortcut'].values.tolist()
def TopFuzzMatch(tokenA, dict_, position, value):
"""
Calculates similarity between two tokens and returns TOP match and score
-----------------------------------------------------------------------
tokenA: similarity to this token will be calculated
dict_a: list with shortcuts
position: whether I want first, second, third...TOP position
value: 0=similarity score, 1=associated shortcut
-----------------------------------------------------------------------
"""
sim = [(fuzz.token_sort_ratio(x, tokenA),x) for x in dict_]
sim.sort(key=lambda tup: tup[0], reverse=True)
return sim[position][value]
df_cam['1st_choice_short'] = df_cam.apply(lambda x: TopFuzzMatch(x['cli_origin'],list_values,0,1), axis=1 )
df_cam['1st_choice_sim'] = df_cam.apply(lambda x: TopFuzzMatch(x['cli_origin'],list_values,0,0), axis=1 )
请注意,我还想计算第二和第三最佳匹配来评估准确性。
编辑
我找到了process.ExtractOne 方法,但速度保持不变。
所以我的代码现在看起来像这样:
def TopFuzzMatch(token, dict_, value):
score = process.extractOne(token, dict_, scorer=fuzz.token_sort_ratio)
return score[value]
【问题讨论】:
标签: python fuzzywuzzy