2016-07-13 3 views
2

重複する可能性のある映画タイトルのリストは2つありますが、異なる書式で書かれている可能性があります。
パンダとは2つの異なるデータフレームにあります。いくつかの良い品質の結果を与える映画のタイトルとdifflibとpandasをあいまいにする方法は?

df1.title.map(lambda x: process.extractOne(x, choices=df2.title, score_cutoff=95)) 

:だから私はそうのようなfuzzywuzzyライブラリとmap()機能を使用しようとしました。しかし、時間の複雑さは、私は両方のデータフレームの非常に小さなサブセットでしか実行できないほどです。データフレームのサイズを増やしてみると、すぐに使用できなくなります。

次に、fuzzywuzzydifflibに置き換えようとしました。そしてはるかに高速です。しかし、私が望む結果を得ることはできません。

は、最初に私が試した:

df1.title.map(lambda x: difflib.get_close_matches(x, df2.title, n=1) 

そして、それは速かったが、結果の品質が劣っていました。単純な大文字/小文字の変更が欠落しています。 cutoffで遊んでも役に立ちませんでした。

私は間違ったツールを使用していると思いました。ドキュメントや例では、私はget_close_matchesがシングルワードで使われているのを見ました。タイトルにはさまざまな言葉があります。

SequenceMatcherはより良い選択ですか?

もしそうなら、それをmap()にどのように適合させるのですか?上記の関数と同じことをします:最良の結果のみを返し、結果が特定の比率を超える場合のみですか?

答えて

0

私は、この問題を解決することを目的とPythonパッケージを書かれています。とりわけ、問題のn^2複雑さに対処します(たとえば、長さ100のデータセットを2つ、コードに10,000の比較が必要)。

あなたがレポhereとドキュメントhereを見つけることができますpip install fuzzymatcher

を使用してインストールすることができます。

基本的な使用法:あなたはファジー化する2つのデータフレームdf_leftdf_rightを、与えられた

が参加、あなたは次のように記述することができます

from fuzzymatcher import link_table, left join 

# Columns to match on from df_left 
left_on = ["fname", "mname", "lname", "dob"] 

# Columns to match on from df_right 
right_on = ["name", "middlename", "surname", "date"] 

# The link table potentially contains several matches for each record 
fuzzymatcher.link_table(df_left, df_right, left_on, right_on) 

それとも、ただ最も近い一致にリンクしたい場合:

fuzzymatcher.fuzzy_left_join(df_left, df_right, left_on, right_on) 
+0

大変必要なパッケージです。しかし、HDDには4Gbの「Visual C++ Build Tools」が必要です。 – user2978216

+0

興味深い - あなたはWindows上にいると思いますか?あなたはすでにpandas/numpyがインストールされていますか?エラーメッセージがどこでいつ取得されるのか詳細を教えてください。 – RobinL

+0

私はWindows上で、pandas/numpyがインストールされています。インストールの試行で[エラーメッセージ]が表示される(https://imgur.com/a/DXD5g) – user2978216

1

大文字と小文字の違いによる低スコアの一致の可能性を排除するには、一致する列に.upper()または.lower()を指定することをおすすめします。大文字と小文字を調整した後、すべてのタイトルのリストをThisListにコンパイルし、toleranceという次の関数を使用してください(SequenceMatcherに頼ってください)。

def fuzzy_group_list_elements(ThisList,Tolerance): 
    from difflib import SequenceMatcher 
    Groups = {} 
    TempList = ThisList.copy() 
    for Elmt in TempList: 
     if Elmt not in Groups.keys(): 
      Groups[Elmt] = [] 
     for OtherElmt in TempList: 
      if SequenceMatcher(None,Elmt,OtherElmt).quick_ratio() > Tolerance: 
       Groups[Elmt] = Groups[Elmt] + [OtherElmt] 
       TempList.remove(OtherElmt) 
    Groups[Elmt] = list(set(Groups[Elmt])) 
    return dict((v,k) for k in Groups for v in Groups[k]) 

その後、映画のタイトルを含むデータフレームの列に上記の関数を適用することができます。

Mapping = fuzzy_group_list_elements(ThisList,0.85) 
df['Matched Title'] = df['Title'].replace(Mapping) 
関連する問題