编辑以回应您的评论:
In [164]: df = pd.DataFrame({'col1': ['maria','fred','john'], 'col2': ['mary','orange','maria']})
使所有组合(玛丽亚,玛丽),(玛丽亚,橙色),(玛丽亚,玛丽亚),(弗雷德......)
In [165]: combos = itertools.product(df.col1, df.col2)
combos
将是一个扁平的元组列表,总共有('maria', 'mary') ...,
9 个。由于我们需要每个名称的最佳匹配,我们需要按名称对元组进行分组col1
。
In [166]: groups = [list(g) for k, g in itertools.groupby(combos, lambda x: x[0])]
现在我们有一个包含三个列表的列表:[[('maria', 'mary'), ('maria', 'orange'), ('maria', 'maria')], [...]]
. 第二个参数groupby
是分解组的键。查看itertools 文档。
In [167]: groups
Out[167]:
[[('maria', 'mary'), ('maria', 'orange'), ('maria', 'maria')],
[('fred', 'mary'), ('fred', 'orange'), ('fred', 'maria')],
[('john', 'mary'), ('john', 'orange'), ('john', 'maria')]]
定义一个辅助函数:
def get_best(group):
k = group[0][0]
ratios = {x[1]: difflib.SequenceMatcher(None, *x).ratio() for x in group}
winner = max(ratios.iteritems(), key=lambda x: x[1])
return winner[1] # mess with this to return original name, mathcihng name, ratio
这是您将应用于groups
. 就像我们之前的手对SequenceMatcher
来获得比率一样。只是现在我们需要保留这个名字。所以在那个函数x
中有一个像('maria', 'mary')
. 我们需要知道最佳匹配中的名称和最佳匹配的比例,因此我将它们放入带有{name: ratio}
. 这里的另一件事是max
需要第二个参数。这次只是说要最大化的是x[1]
,比率。
并获得最佳匹配:
In [173]: best = [get_best(group) for group in groups]
In [175]: df['best_match'] = best
In [176]: df
Out[176]:
col1 col2 best_match
0 maria mary maria
1 fred orange orange
2 john maria orange
[3 rows x 3 columns]
这应该是相当有效的。