我有一个带有cli id和origin的数据框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]
答案 0 :(得分:1)
我找到了一个解决方案 - 在用正则表达式清理原始列(没有数字和特殊字符)之后,只有几百个重复的不同值,所以我只计算那些Fuzz算法,这显着改善了时间。
int numericValue = Character.getNumericValue(toInteger) + 1; // Note the parenthesis
String asString = String.valueOf(numericValue);
String prefix = str.subString(9);
String suffix = str.subString(10, str.length());
str = prefix + asString + suffix;