2016-07-25 7 views
5

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

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) 

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

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

ответ

7

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

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) 

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

+0

Это отличный ответ! Но, для больших файлов (~ lakhs), я получаю ошибку памяти – user1930402