web-dev-qa-db-ja.com

データフレーム列全体にあいまい一致を適用し、結果を新しい列に保存します

2つのデータフレームがあり、それぞれの行数が異なります。以下は、各データセットからのいくつかの行です

_df1 =
     Company                                   City         State  Zip
     FREDDIE LEES AMERICAN GOURMET SAUCE       St. Louis    MO     63101
     CITYARCHRIVER 2015 FOUNDATION             St. Louis    MO     63102
     GLAXOSMITHKLINE CONSUMER HEALTHCARE       St. Louis    MO     63102
     LACKEY SHEET METAL                        St. Louis    MO     63102
_

そして

_df2 = 
     FDA Company                    FDA City    FDA State   FDA Zip
     LACKEY SHEET METAL             St. Louis   MO          63102
     PRIMUS STERILIZER COMPANY LLC  Great Bend  KS          67530
     HELGET GAS PRODUCTS INC        Omaha       NE          68127
     ORTHOQUEST LLC                 La Vista    NE          68128
_

combined_data = pandas.concat([df1, df2], axis = 1)を使用して並べて結合しました。次の目標は、_df1['Company']_モジュールのいくつかの異なる一致コマンドを使用して、_df2['FDA Company']_の下の各文字列を_fuzzy wuzzy_の下の各文字列と比較し、最適な一致の値とその名前を返すことです。それを新しい列に保存したいと思います。たとえば、_fuzz.ratio_から_fuzz.token_sort_ratio_の_LACKY SHEET METAL_で_df1['Company']_と_df2['FDA Company']_を実行した場合、最適な一致は_LACKY SHEET METAL_であり、スコアは_100_で、これは_combined data_の新しい列に保存されます。結果は次のようになります

_combined_data =
     Company                                   City         State  Zip      FDA Company                     FDA City    FDA State   FDA Zip     fuzzy.token_sort_ratio    match    fuzzy.ratio         match
     FREDDIE LEES AMERICAN GOURMET SAUCE       St. Louis    MO     63101    LACKEY SHEET METAL              St. Louis   MO          63102       LACKEY SHEET METAL        100      LACKEY SHEET METAL  100
     CITYARCHRIVER 2015 FOUNDATION             St. Louis    MO     63102    PRIMUS STERILIZER COMPANY LLC   Great Bend  KS          67530
     GLAXOSMITHKLINE CONSUMER HEALTHCARE       St. Louis    MO     63102    HELGET GAS PRODUCTS INC         Omaha       NE          68127
     LACKEY SHEET METAL                        St. Louis    MO     63102    ORTHOQUEST LLC                  La Vista    NE          68128
_

やってみた

_combined_data['name_ratio'] = combined_data.apply(lambda x: fuzz.ratio(x['Company'], x['FDA Company']), axis = 1) 
_

しかし、列の長さが異なるため、エラーが発生しました。

私は困惑しています。どうすればこれを達成できますか?

10
Jstuff

私はあなたが何をしていたのか分かりませんでした。これが私がそれをする方法です。

from fuzzywuzzy import fuzz
from fuzzywuzzy import process

比較する一連のタプルを作成します。

compare = pd.MultiIndex.from_product([df1['Company'],
                                      df2['FDA Company']]).to_series()

ファジーメトリックを計算して系列を返す特別な関数を作成します。

def metrics(tup):
    return pd.Series([fuzz.ratio(*tup),
                      fuzz.token_sort_ratio(*tup)],
                     ['ratio', 'token'])

metricscompareシリーズに適用します

compare.apply(metrics)

enter image description here

この次の部分を実行する方法はたくさんあります。

df1の各行に最も近い一致を取得します

compare.apply(metrics).unstack().idxmax().unstack(0)

enter image description here

df2の各行に最も近い一致を取得します

compare.apply(metrics).unstack(0).idxmax().unstack(0)

enter image description here

14
piRSquared