如何在 python pandas 中查找并纠正数据框中的拼写错误

Rav*_*rip 5 python dataframe pandas

我有一个包含姓名、生日和一些随机变量的数据框。可以说它看起来像这样:

    BIRTH  NAME    SURNAME random_value institution
 1      1  Luke  Skywalker            1        1111
 2      1  Luke  Skywalker            2        1111
 4      2  Leia     Organa            3        1211
 5      3   Han       Solo            7        1342
 7      1   Ben       Solo            1        1342
 8      5 Lando Calrissian            3        1111
 9      3   Han       Solo            4        1111
 10     3   Ham       Solo            4        1342
 11     1  Luke  Wkywalker            9        1111
Run Code Online (Sandbox Code Playgroud)

如何根据 、和BIRTH判断姓名或姓氏是否存在拼写错误,然后用正确的姓名或姓氏替换拼写错误?NAMESURNAME

例如,我们看到,有两个Han Solos 具有生日3,然后有一个Ham Solo具有相同的生日。我希望这个算法做的是找出Ham错误并将其替换为Han.

如果有两种不同的拼写具有相同的出现次数(对于 same BIRTH),选择哪一个并不重要,只要该组的所有 或NAME都是SURNAME相同的(因此总是HamHan但不混合相同的BIRTH)。

所以最终的结果是这样的:

    BIRTH  NAME    SURNAME random_value institution
 1      1  Luke  Skywalker            1        1111
 2      1  Luke  Skywalker            2        1111
 4      2  Leia     Organa            3        1211
 5      3   Han       Solo            7        1342
 7      1   Ben       Solo            1        1342
 8      5 Lando Calrissian            3        1111
 9      3   Han       Solo            4        1111
 10     3   Han       Solo            4        1342
 11     1  Luke  Skywalker            9        1111
Run Code Online (Sandbox Code Playgroud)

有没有自动化的方法来做到这一点?我的数据集很大(>3mill 行),不可能手动检查。

我想我们会查找所有具有相同出生的名字和姓氏,然后检查是否存在一些仅因字母不同的奇异异常值,或者字母的顺序是否被交换(Lukevs Lkue)。当我们发现这样的异常值时,我们会替换它。

我已经在R论坛中询问过这个问题(如何在数据框中查找拼写错误并替换它)并得到了回复。我尝试直接实现该方法(由于时间复杂性,它惨遭失败)。然后我对其进行了修改并将其用于较小的子数据帧(按 分组BIRTH)。但即便如此,我还是停止了这个过程,因为R估计需要 37 个小时以上,而且这个数字还在攀升。

有没有更快的方法可以在python. 如果您能给我任何建议,我将非常感激。

编辑:正如评论中所指出的,有可能两个名字相似的人(乔恩/约翰·斯密特(h))将在同一天出生。在这种情况下,我们要么查看机构栏(每个人应该(但数据集的实际情况可能有点不同)一个机构编号出现 8-9 次,另一个机构编号出现 3-4 次)。此外,不止一个人共享同一机构编号。

但由于 的数据可能有错误institution,我们还可以使用以下推理:如果同一生日的相同全名出现两次以上,我们可以断定它实际上是一个新人,而不是拼写错误(因为两个(out最多 13 个)同一个人不太可能有相同的拼写错误),并保留其名称不变。

Fra*_*ayr 0

首先,我将出生与姓名分组,并列出所得的姓氏。所以我会得到

['Fkywalker', 'Skywalker', 'Skywalker'] 
Run Code Online (Sandbox Code Playgroud)

之后,我找出出现次数最多的名字(天行者),并将其他名字与这个名字进行比较。为了查找拼写错误,我计算了Levenshtein-distance。当距离低于 3 时,我认为这是一个拼写错误并更新如下字典:

{'wrong_name' : 'right_name'}
Run Code Online (Sandbox Code Playgroud)

然后我对这些名字进行同样的过程。

然后你就有了两个替换字典,你可以简单地替换错误的值。

    import pandas as pd
    import distance
    from collections import Counter 

    dict_SURNAME = dict()
    dict_NAME = dict()

    def dist(str1, str2):
        return distance.levenshtein(str1, str2)

    def find_name(namelist, todict):
        for names in namelist:
            namesorted = Counter(names).most_common()
            for name in namesorted[1:]:
                if dist(namesorted[0][0], name[0]) < 3:
                    todict.update({name[0]: namesorted[0][0]})

    dfsurname = df1.groupby(['BIRTH', 'NAME']).SURNAME.apply(list).reset_index()
    find_name(dfsurname.SURNAME.tolist(), dict_SURNAME)

    dfname = df1.groupby(['BIRTH', 'SURNAME']).NAME.apply(list).reset_index()
    find_name(dfname.NAME.tolist(), dict_NAME)

    print(dict_SURNAME)
    print(dict_NAME)

    df2 = df1.replace({'NAME': dict_NAME, 'SURNAME': dict_SURNAME})
    print(df2)
Run Code Online (Sandbox Code Playgroud)