我有df_cam
带有 cli id 和来源的 DataFrame A ( ):
cli id | origin
------------------------------------
123 | 1234 M-MKT XYZklm 05/2016
df_dict
和带有快捷方式和活动的DataFrame B ( )
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]