Примените нечеткое сопоставление к столбцу данных и сохраните результаты в новом столбце.

У меня есть два фрейма данных, каждый из которых имеет разное количество строк. Ниже пара строк из каждого набора данных

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) 

Но получил ошибку, потому что длины столбцов разные.

Я в тупике. Как я могу это сделать?

 Nikhil VJ20 авг. 2018 г., 16:56
зачем совмещать столы рядом? В конечном итоге вы хотите проверить каждое имя в df1 на каждое имя в df2 и выбрать имя с наибольшим количеством очков, верно? Простой цикл iterrows с df2.name.apply (fuzz.ratio (...)) внутри должен это сделать.

Ответы на вопрос(1)

Решение Вопроса

Я не мог сказать, что ты делал. Вот как бы я это сделал.

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

Применятьmetrics кcompare серии

compare.apply(metrics)

Есть несколько способов сделать это в следующей части:

Получите самые близкие совпадения к каждому рядуdf1

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

Получите самые близкие совпадения к каждому рядуdf2

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

 pvarma04 авг. 2017 г., 08:26
Это отличный ответ! Но для больших файлов (~ lakhs) я получаю ошибку памяти

Ваш ответ на вопрос