2016-11-07 78 views
1

我有兩個不同的數據框,我需要合併和合並列('標題')需要清理之前合併可能發生。示例數據示例如下所示;合併之前清理數據的更好方法是什麼?

data1 = pd.DataFrame({'id': ['a12bcde0','b20bcde9'], 'title': ['a.b. company','company_b']}) 

data2 = pd.DataFrame({'serial_number': ['01a2b345','10ab2030','40ab4060'],'title':['ab company','company_b (123)','company_f']}) 

如預期的那樣,第一個標題的合併不會成功。我一直在使用replace()方法,但由於拼寫,區分大小寫等因素導致我有100個標題需要糾正,因此我的方法很難實現。

有關如何最佳清理和合並數據的其他建議?

完整的例子:

import pandas as pd 
import numpy as np 

data1 = pd.DataFrame({'id': ['a12bcde0','b20bcde9'], 'title': ['a.b. company','company_b']}) 

data2 = pd.DataFrame({'serial_number': ['01a2b345','10ab2030','40ab4060'],'title':['ab company','company_b (123)','company_f']}) 

data2['title'].replace(regex=True,inplace=True,to_replace=r"\s\(.*\)",value=r'') 

replacements = { 
    'title': { 
     r'a.b. company *.*': 'ab company' 
    } 
} 
data1.replace(replacements, regex=True, inplace=True) 

pd.merge(data1, data2, on='title') 
+0

我想不出比這更好的辦法......你在想什麼? – maxymoo

+1

您可以使用['fuzzywuzzy'](https://pypi.python.org/pypi/fuzzywuzzy)包,並使用函數「ratio」作爲例子。 – IanS

回答

2

第一件事,對於這個問題沒有完美的解決方案,但我建議做兩件事情:

  • 做任何易於清洗,你可以d o事前,包括刪除你不期望的任何字符。
  • 應用一些模糊匹配邏輯

你會看到這是不完美的,因爲即使這個例子不起作用100%個百分點。


首先,讓我們通過使您的例子一點點複雜,引入定期錯字(coampany_b而不是company_b,這東西不會被下面的清洗容易得到回升)

data1 = pd.DataFrame({'id': ['a12bcde0','b20bcde9', 'csdfsjkbku'], 'title': ['a.b. company','company_b', 'coampany_b']}) 
data2 = pd.DataFrame({'serial_number': ['01a2b345','10ab2030','40ab4060'],'title':['ab company','company_b (123)','company_f']}) 
啓動

然後讓我們假設你只希望[az]字符作爲@MaartenFabré提到。所以讓我們小寫一切並刪除其他內容。

data1['cleaned_title'] = data1['title'].str.lower().replace(regex=True,inplace=False,to_replace=r"[^a-z]", value=r'') 
data2['cleaned_title'] = data2['title'].str.lower().replace(regex=True,inplace=False,to_replace=r"[^a-z]", value=r'') 

現在,讓我們使用difflib's get_close_matches(閱讀更多和其他選項here

import difflib 
data1['closestmatch'] = data1.cleaned_title.apply(lambda x: difflib.get_close_matches(x, data2.cleaned_title)[0]) 
data2['closestmatch'] = data1.cleaned_title.apply(lambda x: difflib.get_close_matches(x, data2.cleaned_title)[0]) 

這裏是造成DATA1,好看!

id   title   cleaned_title closestmatch 
0 a12bcde0 a.b. company abcompany  abcompany 
1 b20bcde9 company_b  companyb  companyb 
2 csdfsjkbku coampany_b  coampanyb  companyb 

現在,這裏是數據2,看起來有點不太好的 ......我們要求它找到最接近的匹配,所以它發現一個company_f,而你顯然不希望它。

serial_number title   cleaned_title closestmatch 
0 01a2b345  ab company  abcompany  abcompany 
1 10ab2030  company_b (123) companyb  companyb 
2 40ab4060  company_f  companyf  companyb 

理想的情況是,如果你有在旁邊公司的標題,在這種情況下,你會發現基礎上最匹配的清潔列表。如果你不這樣做,你必須有創意或手動清理命中和錯過。

爲了解決這個問題,您現在可以在'最近匹配'上執行常規合併。

0

您可以嘗試通過將所有字符轉換爲小寫,並刪除所有非[AZ]字符以使各2個dataframes的simplified_name柱和加入此列,如果這不會導致衝突第一

相關問題