2016-11-07 77 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柱和加入此列,如果这不会导致冲突第一

相关问题