Частичное сопоставление строк в группах

У меня есть данные, которые включают группу (область), а затем также предоставляют имя. Я пытаюсь объединить два фрейма данных. Один кадр намного меньше и является кадром данных «отображения». Он имеет одну строку для каждого имени в области. Другой фрейм намного больше и является фреймом данных «экземпляры». В нем много строк с вариациями названий с Районом. Я хочу, чтобы информация из фрейма сопоставления была объединена с фреймом экземпляров, чтобы каждый экземпляр имел информацию, которую ему предоставляет фрейм сопоставления.

Я изучил пакет Fuzzy, но не нашел способа реализовать его в группах (столбец «Область») или как эффективно использовать его с ячейками, содержащими несколько строк, и пытаться сопоставить их на основе этого.

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

Сопоставление кадра данных

Area    Name
A   Apple  
A   Orange Strawberry 
A   Blackberry Rasberry 
B   Blackberry 
C   Kiwi  
C   Apple  

Экземпляры

Area    Locale
A   Apple Pear Tomato
A   Orange Potato Strawberry Zuccini
A   Blackberry Rasberry 
B   Blackberry Onion
B   Lettuce Blackberry Cucumber 
C   Kiwi Spinach Pineapple
C   Kiwi Potato 
C   Apple Cucumber 
C   Apple Potato 

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

Датафрейм

Area    Locale                                  Name
A   Apple Pear Tomato                   Apple  
A   Orange Potato Strawberry Zuccini    Orange Strawberry 
A   Blackberry Rasberry                 Blackberry Rasberry 
B   Blackberry Onion                    Blackberry 
B   Lettuce Blackberry Cucumber.        Blackberry 
C   Kiwi Spinach Pineapple              Kiwi  
C   Kiwi Potato                         Kiwi  
C   Apple Cucumber                      Apple 
C   Apple Potato                        Apple 

person Kskiaskd    schedule 25.04.2019    source источник
comment
ты решил это? ты в итоге воспользовался моим ответом? Дайте мне знать, если я могу помочь вам дальше!   -  person RenauV    schedule 30.04.2019


Ответы (1)


Используя пух и панды, вы можете получить ожидаемый результат.

1) начните со сбора ваших библиотек и данных:

import pandas as pd
from fuzzywuzzy import fuzz
mapping = pd.read_excel('Book1.xlsx', sheet_name='mapping')
instance = pd.read_excel('Book1.xlsx', sheet_name='instance')

2) создайте список уникальных значений ваших областей:

unique_area = instance['Area'].drop_duplicates(keep='first').values.tolist()

3) создайте пустой кадр данных и запустите для каждой области следующий код:

fuzzed_data = []
for i in unique_area:
    instanceunique = instance[instance['Area'] == i]
    unique_list = mapping[mapping['Area'] == i]['Name'].drop_duplicates(keep='first').values.tolist()
    instance_score = instanceunique[['Locale']]
    for i in unique_list:
        ratiofuzz = []
        for index, row in instance_score.iterrows():
                ratiofuzz.append(fuzz.ratio(row['Locale'], i))
        instance_score[i] = ratiofuzz
    scores = instance_score.drop(['Locale'], axis=1)
    instance_score['mapping'] = scores.idxmax(axis=1)
    instanceunique = pd.merge(instanceunique
                          , instance_score[['Locale', 'mapping']]
                          , how='left'
                          , on=['Locale'])
    fuzzed_data.append(instanceunique)

4) Объедините «нечеткие» данные:

fuzzed_data = pd.concat(fuzzed_data, axis=0)

Вот и все! Дай мне знать, если тебе еще понадобится помощь. BR

person RenauV    schedule 25.04.2019
comment
Благодарю за ваш ответ. После запуска кода я получил ошибку «Длина значений не соответствует длине индекса». - person Kskiaskd; 25.04.2019
comment
Я попробовал это, и это сработало на моей стороне с примером, который вы привели выше. Может быть, вы не используете те же данные? Также обратите внимание, что последняя часть (pd.concat) находится вне цикла. - person RenauV; 25.04.2019