2017-09-02 37 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)