2017-01-04 8 views
1

I 50,000一意の行及び20列の次パンダのデータフレーム(付属は、関連する列の抜粋である)を有する:は別のデータフレームにファジーマッチのための1つのPythonデータフレーム/辞書を検索

DF1

  PRODUCT_ID   PRODUCT_DESCRIPTION 
0   165985858958   "Fish Burger with Lettuce" 
1   185965653252   "Chicken Salad with Dressing" 
2   165958565556   "Pork and Honey Rissoles" 
3   655262522233   "Cheese, Ham and Tomato Sandwich" 
4   857485966653   "Coleslaw with Yoghurt Dressing" 
5   524156285551   "Lemon and Raspberry Cheesecake" 

Iも2列20,000一意の行いる(私はまた、辞書形式で保存されている)は、以下のデータフレームを有する:

DF2(またジとして保存しますct_2)私がやりたいと思っています何

 PROD_ID PROD_DESCRIPTION 
0  548576 "Fish Burger" 
1  156956 "Chckn Salad w/Ranch Dressing" 
2  257848 "Rissoles - Lamb & Rosemary" 
3  298770 "Lemn C-cake" 
4  651452 "Potato Salad with Bacon" 
5  100256 "Cheese Cake - Lemon Raspberry Coulis" 

はDF2に「PROD_DESCRIPTION」フィールドにDF1に「PRODUCT_DESCRIPTION」フィールドを比較して、重い物を持ち上げるの一部を支援するために最も一致/マッチを見つけることです。私は手動で一致をチェックする必要がありますが、それはずっと速くなります。理想的な結果は以下のようになります。 1つまたは複数の部分一致が記載されています:

 PRODUCT_ID  PRODUCT_DESCRIPTION    PROD_ID PROD_DESCRIPTION 
0 165985858958 "Fish Burger with Lettuce"  548576 "Fish Burger" 
1 185965653252 "Chicken Salad with Dressing"  156956 "Chckn Salad w/Ranch Dressing" 
2 165958565556 "Pork and Honey Rissoles"   257848 "Rissoles - Lamb & Rosemary"  
3 655262522233 "Cheese, Ham and Tomato Sandwich" NaN  NaN 
4 857485966653 "Coleslaw with Yoghurt Dressing" NaN  NaN 
5 524156285551 "Lemon and Raspberry Cheesecake" 298770 "Lemn C-cake" 
6 524156285551 "Lemon and Raspberry Cheesecake" 100256 "Cheese Cake - Lemon Raspberry Coulis" 

私は既に完全一致を特定した結合を完了しました。各dfのProduct IDが一意であるため、インデックスが保持されることは重要ではありません。結果は、新しいデータフレームに保存することもできます。これは、約1400万行の第3のデータフレームに適用されます。

私は(とりわけ)以下の質問と回答を使用しました:

Is it possible to do fuzzy match merge with python pandas
Fuzzy merge match with duplicatesはしようとクラゲモジュールを含む
Python fuzzy matching fuzzywuzzy keep only the best match
Fuzzy match items in a column of an array

も様々な回答の1で提案されているようにループ/関数/マッピングなどであるが、スコアが低い、またはマッチが検出されない最初の「ファジー一致」を得るか、またはいずれも成功しなかった。

hereとして一致/距離スコアの列が生成されるというアイデアが好きです。これは手動確認プロセスのスピードアップを可能にします。

私はPython 2.7、pandasを使用しており、fuzzywuzzyがインストールされています。

答えて

2

メトリック私の距離としてfuzz.ratioを使用して、この

ように私の距離行列を計算します
df3 = pd.DataFrame(index=df.index, columns=df2.index) 

for i in df3.index: 
    for j in df3.columns: 
     vi = df.get_value(i, 'PRODUCT_DESCRIPTION') 
     vj = df2.get_value(j, 'PROD_DESCRIPTION') 
     df3.set_value(
      i, j, fuzz.ratio(vi, vj)) 

print(df3) 

    0 1 2 3 4 5 
0 63 15 24 23 34 27 
1 26 84 19 21 52 32 
2 18 31 33 12 35 34 
3 10 31 35 10 41 42 
4 29 52 32 10 42 12 
5 15 28 21 49 8 55 

許容距離のしきい値を設定します。私が設定した50
すべての行に最大値を持つインデックス値(df2)を検索します。

threshold = df3.max(1) > 50 
idxmax = df3.idxmax(1) 

割り当て

df['PROD_ID'] = np.where(threshold, df2.loc[idxmax, 'PROD_ID'].values, np.nan) 
df['PROD_DESCRIPTION'] = np.where(threshold, df2.loc[idxmax, 'PROD_DESCRIPTION'].values, np.nan) 
df 

enter image description here

+0

私はデータの小さなサブセットでこれを使ってきたし、それがうまく機能しているように見えることを確認します。私はちょうど4つの異なる反復で大きなブロックを実行して、さまざまなファズの使用法(つまりfuzz.ratio、fuzz.partial_ratioなど)をテストするように設定しました。私の論文を重く持ち上げて助けてくれてありがとう。 – gincard

+1

追加するだけで - fuzz.token_sort_ratioが約70%の成功した試合で最も正確な結果を出しました。 – gincard

+0

@ gincardどのくらいのデータとどのくらいの速さでしたか...約 – piRSquared

0

あなたは、両方のデータフレームを反復し、ご希望の情報を第3データフレームのdictのいずれかを移入することができるはずです。

d = { 
    'df1_id': [], 
    'df1_prod_desc': [], 
    'df2_id': [], 
    'df2_prod_desc': [], 
    'fuzzywuzzy_sim': [] 
} 
for _, df1_row in df1.iterrows(): 
    for _, df2_row in df2.iterrows(): 
     d['df1_id'] = df1_row['PRODUCT_ID'] 
     ... 
df3 = pd.DataFrame.from_dict(d) 
関連する問題