Столбцы нечеткого совпадения в другом датафрейме - PullRequest
0 голосов
/ 10 сентября 2018

Фон

У меня есть 2 кадра данных, у которых нет общего ключа, к которому я могу их объединить. Оба df имеют столбец, который содержит «имя сущности». Один df содержит 8000+ сущностей, а другой - около 2000 сущностей.

Пример данных :

vendor_df=
     Name of Vendor                             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

regulator_df = 
     Name of Entity                    Committies
     LACKEY SHEET METAL                 Private
     PRIMUS STERILIZER COMPANY LLC      Private  
     HELGET GAS PRODUCTS INC            Autonomous
     ORTHOQUEST LLC                     Governmant  

Stmt задачи:

Я должен нечетко сопоставить сущности этих двух (Name of vendor & Name of Entity) столбцов и получить оценку. Таким образом, необходимо знать, совпадает ли 1-е значение кадра данных 1 (vendor_df) с любым из 2000 объектов кадра данных2 ( regulator_df ).

Ссылки StackOverflow, которые я проверял :

нечеткое совпадение между двумя столбцами (Python)

создать новый столбец в фрейме данных, используя fuzzywuzzy

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

Код

import pandas as pd
from fuzzywuzzy import fuzz
from fuzzywuzzy import process

vendor_df = pd.read_excel('C:\\Users\\40101584\\Desktop\\AUS CUB AML\\Vendors_Sheet.xlsx', sheet_name=0)

regulator_df = pd.read_excel('C:\\Users\\40101584\\Desktop\\AUS CUB AML\\Regulated_Vendors_Sheet.xlsx', sheet_name=0)

compare = pd.MultiIndex.from_product([vendor_df['Name of vendor'],
                                      regulator_df['Name of Entity']]).to_series()


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

#compare.apply(metrics) -- Either this works or the below line

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

Проблемы с кодом выше :

Код работает, если два фрейма данных малы, но он занимает вечность, когда я даю полный набор данных. Код выше взят из 3-й ссылки.

Любое решение, если одно и то же может работать быстро или с большим набором данных?

ОБНОВЛЕНИЕ 1

Можно ли выполнить приведенный выше код быстрее, если мы передадим или жестко закодируем счет, скажем, 80, который отфильтрует серию / фрейм данных только с fuzzyscore> 80?

1 Ответ

0 голосов
/ 11 сентября 2018

Решение ниже, чем я написал, но если у кого-то есть более быстрый подход, скажите:

matched_vendors = []

for row in vendor_df.index:
    vendor_name = vendor_df.get_value(row,"Name of vendor")
    for columns in regulator_df.index:
        regulated_vendor_name=regulator_df.get_value(columns,"Name of Entity")
        matched_token=fuzz.partial_ratio(vendor_name,regulated_vendor_name)
        if matched_token> 80:
            matched_vendors.append([vendor_name,regulated_vendor_name,matched_token])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...