Присоединиться к Dataframes на основе частичных совпадений строк в Python - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть два фрейма данных с общими именами ключевых продуктов. Я хочу создать третий фрейм данных, соединив два предыдущих на основе частичных совпадений строк с сходством 80-90%, наборы данных довольно большие, у меня былопопытался использовать tfidf из scikit-learn, но я продолжаю терять свой ссылочный индекс.В приведенном ниже примере: мини беспроводная Bluetooth спортивная стереогарнитура и защитный чехол OnePlus 6 Sandstone оба должны входить в df3, помощь будет высоко ценится.Выходные данные 1

Пример-

import pandas as pd
df1=pd.DataFrame({'Product_Name1': ['Mini  Wireless Bluetooth Sports Stereo Headset', 'VR Box 3D Smart Glass With Remote Controller', 'OnePlus 6 Sandstone Protective Case'],'Price1': [40000, 50000, 42000]})
df2=pd.DataFrame({'Product_Name2': ['Mini  Wireless Sports Stereo Headset', 'VR Box 3D Smart Glass With Remote Controller', 'OnePlus 6 1Sandstone Protective Case'], 'Price2': [40000, 50000, 42000]})
df1set=df1.set_index('Product_Name1')
df2set=df2.set_index('Product_Name2')
df3=df1set.join(df2set,how='inner')
df3
df1
df2

Первый кадр данных

Второй кадр данных

1 Ответ

0 голосов
/ 19 декабря 2018

Что вам нужно, это нечеткое соответствие.Нечеткое сопоставление используется для сравнения строк, которые очень похожи друг на друга.Для этого вы можете использовать fuzzy wuzzy.

Пример нечеткого сопоставления

from fuzzywuzzy import process
process.extractOne('Mini Wireless Bluetooth Sports Stereo Headset', df2.Product_Name2)

('Mini  Wireless Sports Stereo Headset', 95, 0)

Это значение соответствует 95%.

Я изменил порядок df2 для демонстрации.

df1=pd.DataFrame({'Product_Name1': ['Mini  Wireless Bluetooth Sports Stereo Headset', 
                                    'VR Box 3D Smart Glass With Remote Controller',
                                    'OnePlus 6 Sandstone Protective Case'],
                  'Price1': [40000, 50000, 42000]})

df1

    Product_Name1                                   Price1
0   Mini Wireless Bluetooth Sports Stereo Headset   40000
1   VR Box 3D Smart Glass With Remote Controller    50000
2   OnePlus 6 Sandstone Protective Case             42000


df2=pd.DataFrame({'Product_Name2': ['Mini  Wireless Sports Stereo Headset',
                                    'OnePlus 6 1Sandstone Protective Case',
                                    'VR Box 3D Smart Glass With Remote Controller'],
                  'Price2': [40000, 42000, 50000]})

df2

     Product_Name2                                  Price2
0   Mini Wireless Sports Stereo Headset             40000
1   OnePlus 6 1Sandstone Protective Case            42000
2   VR Box 3D Smart Glass With Remote Controller    50000

Теперь мы напишем функцию, которая сопоставляет каждое значение df1 Product_Name1 с каждым значением df2 Product_Name2 и возвращает индексdf2, где он соответствует самому высокому.

def fuzzy(x):
    closest_match = process.extractOne(x, df2.Product_Name2.values)[0]
    index = pd.Index(df2.Product_Name2).get_loc(closest_match)
    return index

Мы используем применить , чтобы получить результат

df1['match'] = df1['Product_Name1'].apply(fuzzy)
df1

Product_Name1                                      Price1   match
0   Mini Wireless Bluetooth Sports Stereo Headset   40000   0
1   VR Box 3D Smart Glass With Remote Controller    50000   2
2   OnePlus 6 Sandstone Protective Case            42000    1

Поскольку у меня нет ожидаемого результата, яобъединю их

pd.merge(df1, df2, left_on='match', right_on=df2.index)

   Product_Name1                                  Price1    match   Product_Name2   Price 2 

0   Mini Wireless Bluetooth Sports Stereo Headset   40000   0        Mini Wireless Sports Stereo Headset            40000
1   VR Box 3D Smart Glass With Remote Controller    50000   2        VR Box 3D Smart Glass With Remote Controller    50000
2   OnePlus 6 Sandstone Protective Case             42000   1        OnePlus 6 1Sandstone Protective Case        42000

Дайте мне знать, если это работает для вас

...