3

我有 2 个可能重叠的电影标题列表,但可能以不同的形式编写。
它们位于熊猫的 2 个不同数据框中。因此,我尝试像这样将map()函数与fuzzywuzzy库一起使用:

df1.title.map(lambda x: process.extractOne(x, choices=df2.title, score_cutoff=95))

这给出了一些高质量的结果。但是时间复杂度如此之高,以至于我只能在两个数据帧的一个非常小的子集上运行它。当我尝试增加数据帧的大小时,它会迅速变得无法使用。

然后我尝试fuzzywuzzydifflib. 而且速度要快得多。但我无法得到我想要的结果。

起初我试过:

df1.title.map(lambda x: difflib.get_close_matches(x, df2.title, n=1)

这很快,但结果的质量很差。甚至遗漏了一些简单的大写/小写更改。玩的cutoff没有帮助。

所以我以为我使用了错误的工具。在我看到的get_close_matches用于单个单词的文档和示例中。标题中有各种各样的词。

SequenceMatcher更好的选择吗?

如果是,那么我如何将其放入 中map(),使其与上述功能相同:仅返回最佳结果,并且仅在结果高于某个比率时才返回?

4

2 回答 2

1

我写了一个 Python 包来解决这个问题。除此之外,它还解决了问题的 n^2 复杂性(例如,对于两个长度为 100 的数据集,您的代码需要 10,000 次比较)。

您可以使用安装它pip install fuzzymatcher

您可以在此处找到 repo并此处找到文档。

基本用法:

给定两个要模糊连接的数据框df_leftdf_right,您可以编写以下内容:

from fuzzymatcher import link_table, left join

# Columns to match on from df_left
left_on = ["fname", "mname", "lname",  "dob"]

# Columns to match on from df_right
right_on = ["name", "middlename", "surname", "date"]

# The link table potentially contains several matches for each record
fuzzymatcher.link_table(df_left, df_right, left_on, right_on)

或者,如果您只想链接最接近的匹配项:

fuzzymatcher.fuzzy_left_join(df_left, df_right, left_on, right_on)
于 2017-12-04T08:52:26.283 回答
1

为了消除因大小写差异而导致低分匹配的可能性,我建议将.upper()or.lower()应用于您要匹配的列。调整大小写后,您可以将所有标题的列表编译到ThisList并应用以下函数(如您所建议的,依赖于SequenceMatcher)与给定的tolerance.

def fuzzy_group_list_elements(ThisList,Tolerance):
    from difflib import SequenceMatcher
    Groups = {}
    TempList = ThisList.copy()
    for Elmt in TempList:
        if Elmt not in Groups.keys():
            Groups[Elmt] = []
        for OtherElmt in TempList:
            if SequenceMatcher(None,Elmt,OtherElmt).quick_ratio() > Tolerance:
                Groups[Elmt] = Groups[Elmt] + [OtherElmt]
                TempList.remove(OtherElmt)
    Groups[Elmt] = list(set(Groups[Elmt]))
    return dict((v,k) for k in Groups for v in Groups[k])

然后,您可以将上述函数应用于包含电影标题的数据框列:

Mapping = fuzzy_group_list_elements(ThisList,0.85)
df['Matched Title'] = df['Title'].replace(Mapping)
于 2016-07-13T14:30:33.393 回答