2016-11-07 9 views
1

マージする必要がある2つの異なるデータフレームがあり、マージカラム( 'title')をマージする前にクリーンアップする必要があります。サンプルデータの例は次のようになります。マージの前にデータを消去するより良い方法はありますか?

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%のパーセントは動作しませんので、あなたは、これは完璧ではありませんがわかりますいくつかのファジー・マッチング・ロジック

を適用します。


まず、のは通常のタイプミス(代わりにcompany_bcoampany_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']}) 

次に、@ MaartenFabréのように[az]文字が必要と仮定します。だから、すべてを小文字にして他のものを削除しましょう。今

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'') 

、ここで

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]) 

(以上および他のオプションhereを読む)さんはdifflib's get_close_matchesを使用してみましょう格好良い、結果として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 

は今、ここにDATA2、あまり良いビットを探している...私たちは、最も近いものを見つけるためにそれを尋ねたので、あなたは明らかにそれを望んでいない一方で、それは、company_fのための1つを見つけました。

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 

あなたはそのに基づいて最も近いものを見つける必要があり、その場合には側の会社のタイトルのクリーンなリストを持っている場合は理想的なケースのシナリオです。あなたがしない場合は、創造的に取得するか、手動でヒットとミスをクリーンアップする必要があります。

これをラップすると、「closestmatch」に対して通常のマージを実行できるようになりました。

0

あなたは小文字にすべての文字を設定し、すべての非[AZ]の文字を除去することにより、2つのデータフレームのそれぞれにおけるsimplified_name列を作成し、この場合、このコラムに参加しようとすることができ衝突

関連する問題