如何在python pandas中查找和更正数据框中的错误

2024-04-28 19:50:23 发布

您现在位置:Python中文网/ 问答频道 /正文

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

    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

如果名字或姓氏有错别字,基于BIRTHNAME和{},然后用正确的名字或姓氏替换这个错误?在

例如,我们看到有两个Han Solo的生日在3上,然后有一个出生日期相同的Ham Solo。我希望这个算法做的是找出Ham是错误的,并用Han替换它。在

如果有两种不同的拼写出现次数相同(对于相同的BIRTH),那么选择哪一种并不重要,只要该组的所有NAME或{}都是相同的(所以总是Ham或{},但不能为同一个BIRTH混合使用)。在

最终的结果是:

^{pr2}$

有没有什么自动化的方法?我的数据集很大(超过3行),无法手动检查。在

我想象一下,我们寻找所有出生相同的名字和姓氏,然后检查是否有一些单独的离群值,它们只在一个字母上不同,或者字母的顺序是交换的(LukevsLkue)。当我们发现这样的离群值时,我们会替换它。在

我已经在R论坛(How to find a typo in a data frame and replace it)上问过这个问题,得到了回复。我试图直接实现那个方法(由于时间复杂性,它失败得很惨)。然后我修改了它并将其用于更小的子数据帧(按BIRTH分组)。但即便如此,我还是停止了这个过程,因为{}估计要花37个小时以上,而且这个数字还在上升。在

python中有没有更快的方法可以做到这一点呢。如果你能给我任何建议,我将不胜感激。在

编辑:正如评论中指出的,有可能两个名字相似的人(Jon/John Smit(h))将在同一日期出生。在这种情况下,我们要么查看机构列(每个人都应该(但数据集的实际情况可能会有所不同)在一个机构编号中出现8-9次,而在另一个机构编号中出现3-4次)。而且,不止一个人共用同一个机构号码。在

但由于institution可能存在错误数据,我们也可以使用以下推理: 如果同一个生日的同一个全名出现两次以上,我们可以得出结论,它实际上是一个新的人,而不是一个打字错误(因为同一个人不太可能有两个(最多13个)完全相同的拼写错误),并保留它的名字。在


Tags: 数据方法name机构错误institution名字solo
1条回答
网友
1楼 · 发布于 2024-04-28 19:50:23

首先,我把出生地和名字分组,并列出由此产生的姓氏。所以我会得到

['Fkywalker', 'Skywalker', 'Skywalker'] 

在那之后,我找出出现次数最多的名字(天行者),并将其他名字与这个名字进行比较。为了找出打字错误,我计算Levenshtein-distance。 当距离低于3时,我假设是打字错误,然后更新一个这样的dict:

^{pr2}$

然后我对名字做同样的程序。在

然后有两个替换dict,您可以简单地替换错误的值。在

    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)

相关问题 更多 >