2017-09-02 73 views
2

我有一个名称,姓氏,生日和一些随机变量的数据框。比方说,它看起来像这样:如何查找和更正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 

我怎样才能弄清楚,如果在名字或姓氏一个错字,基于BIRTHNAMESURNAME,然后请用正确的名字或姓氏错字?

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

如果存在具有出现相等数目的(对于相同BIRTH)两个不同的拼法,它并不重要,选择其中的一个,只要所有的用于该组的NAMESURNAME是相同的(所以总是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 

是否有任何自动化的方式来做到这一点?我的数据集很大(> 3毫米行),并且不可能手动检查。

我想我们会查找所有同名出生的姓氏和名字,然后检查,如果有一些异常的异常值只是一个字母的不同,或者字母顺序被切换(Luke vs Lkue) 。当我们发现这样的异常值时,我们将其替换。

我已经在R论坛(How to find a typo in a data frame and replace it)询问过并获得了答复。我试图直接实现该方法(由于时间复杂性,它失败了)。然后我修改它,并在较小的子数据帧上使用它(按BIRTH分组)。但即使如此,当R估计需要超过37小时,并且这个数字正在攀升时,我停止了这个过程。

python有没有更快的方法来做到这一点。如果你能给我任何建议,我将非常感激。

编辑:正如评论中指出的那样,有两个名字相似的人(Jon/John Smit(h))将会在同一天出生。在这种情况下,我们要么查看机构栏目(每个人应该(但是数据集的实际情况可能有点不同)以一个机构编号出现8-9次,而另一个机构编号出现3-4次)。此外,不止一个人共享相同的机构编号。

但由于可能出现故障的数据与institution的,我们还可以使用以下推理: 如果同一天生日相同的全名出现两次以上,我们可以得出结论,它实际上是一个新的人,而不是一个错字(对于同一个人来说,两个(最多13个)相同的拼写错误不太可能),并且保留它的名字。

+1

你将如何处理类似的,但具有相同的生日的同名的名字?例如。 (B/C)laire(J/D)anes? Jo(h)n Smit(h/t)? –

+0

也许我给了一个不好的示例表。还有另一列,有4位数字的代码。每个人都应该有(在理想条件下)8或9行和4行不同的代码(实际上是他们的机构代码)。也许这是应该考虑到的。或者更简单的是,如果存在“名姓”置换,发生的次数多于两次或三次,我们可以认为它不是一个错字,而是一个不同的人(如同一个错字发生两次或三次人是不太可能的,它必须意味着一个新的人。) – Ravonrip

+1

在这种情况下,考虑更新您的示例以更具代表性的数据 - 以这种方式帮助您会更容易。 –

回答

0

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

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

之后,我找到了最OCCURENCES(天行者)的名称和其他名称与此一比较。为了找到错别字,我计算了Levenshtein-distance。 当距离小于3,我认为这是一个错字和更新这样的字典:

{'wrong_name' : 'right_name'} 

然后我就与名称相同的程序。

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

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)