python - 2个 Pandas 数据框列之间的矢量化/矩阵计算

标签 python string pandas difflib

我使用 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将包含 'maria', 'fred' and 'john' 的最佳匹配基于 df2.col1值(value)观。

我觉得使用 .apply 是可能的方法,但我就是想不通如何计算 df.col1 中的每个值。反对df2.col1 .

更新:difflib.get_close_matches 方法能够更好地处理大型数组,并为我提供了我想要的一切,除了比率分数(没什么大不了的)。 Tom 在下面的回答适用于较小的数据集,但当每列的值约为 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 docs .

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]

这应该是相当有效的。

关于python - 2个 Pandas 数据框列之间的矢量化/矩阵计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21342658/

相关文章:

python - 在 TextCtrl 中禁用光标 - wxPython

c - 在c中解析字符串

python - 忽略 pandas.read_csv() 中破坏 header= keywords 的坏数据行

Java 字符串连接在 concat 1+1 上给出输出 2 等于 11 +"equals"+1+1

统计相似的单词

python - 如何编写Python单元测试列名是字符串?

python - 从多返回值 groupby-apply 操作输出 DataFrame 而不是 Series

python - 两个 DataFrame 与条件的组合

python - 在 python 中使用列表理解扩展列表

python - 从 Python 模块中的 nosetests 获取测试结果