繁体   English   中英

在2个Pandas数据框列之间进行矢量化/矩阵计算

[英]Vectorized/Matrix calculation between 2 Pandas dataframe columns

我正在使用difflib比率来计算2个字符串之间的相似度:

ratio = difflib.SequenceMatcher(None, 'string1', 'string2').ratio()

输出是一个从0-1开始的浮点值,可以解释为匹配分数。

我正在尝试做的是创建一个包含基于值与其他值列表之间的max(ratio)最佳匹配的列。

因此,如果:

df.col1 = 'maria','fred','john'

和:

df2.col1 = 'mary','orange','maria'

df.bestmatch将包含基于df2.col1值的'maria', 'fred' and 'john'的最佳匹配。

我觉得使用.apply方法可以做到这.apply ,但我只是不知道如何针对df2.col1计算df.col1中的每个值。

更新:difflib.get_close_matches方法能够更好地处理大型数组,并为我提供了我想要的一切,除了比率得分(没什么大不了)。 汤姆下面的答案适用于较小的数据集,但是当每列为〜19,000个值时出现MemoryError。

根据您的评论进行了编辑:

In [164]: df = pd.DataFrame({'col1': ['maria','fred','john'], 'col2': ['mary','orange','maria']})

制作所有连击(maria,mary),(maria,orange),(maria,maria),(fred ...)

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]

这应该是相当有效的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM