Как связать два кадра данных на основе сходства строк одного столбца - PullRequest
1 голос
/ 20 сентября 2019

У меня есть два кадра данных, оба имеют идентификатор и столбец Name, который содержит строки.Они могут выглядеть следующим образом:

Фреймы данных:

DF-1                              DF-2
---------------------             ---------------------
     ID          Name                  ID          Name
1    56       aaeessa             1    12    H.P paRt 1 
2    98       1o7v9sM             2    76       aa3esza
3   175    HP. part 1             3   762    stakoverfl 
4     2     stackover             4     2       lo7v9Sm

Я хотел бы вычислить сходство строк (например, Джакарда, Левенштейна) между одним элементом со всемидругие и выберите тот, который имеет самый высокий балл.Затем сопоставьте два идентификатора, чтобы я мог присоединиться к полному фрейму данных позже.Получившаяся таблица должна выглядеть следующим образом:

Результат:

Result
-----------------
     ID1     ID2
1    56       76
2    98        2
3   175       12
4     2      762

Этого легко добиться, используя удвоенный цикл for, но я ищу элегантный(и более быстрый способ), чтобы достичь этого, может быть, понимание списка лямбд, или какой-нибудь инструмент панд.Может быть, некоторая комбинация groupby и idxmax для оценки сходства, но я не могу придумать решение самостоятельно.

РЕДАКТИРОВАТЬ: DataFrames имеют разные длины,одна из целей этой функции состоит в том, чтобы определить, какие элементы меньшего информационного кадра появляются в большем информационном кадре, и сопоставлять их, отбрасывая остальные.Поэтому в результирующей таблице должны появляться только пары идентификаторов, которые совпадают, или пары ID1 - NaN (при условии, что DF-1 имеет больше строк, чем DF-2).

Ответы [ 3 ]

1 голос
/ 20 сентября 2019

Использование пакета pandas dedupe: https://pypi.org/project/pandas-dedupe/

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

сначала pip install pandas-dedupe и попробуйте это:

import pandas as pd
import pandas_dedupe

df1=pd.DataFrame({'ID':[56,98,175],
                 'Name':['aaeessa', '1o7v9sM', 'HP. part 1']})

df2=pd.DataFrame({'ID':[12,76,762,2],
                 'Name':['H.P paRt 1', 'aa3esza', 'stakoverfl ', 'lo7v9Sm']})


#initiate matching
df_final = pandas_dedupe.link_dataframes(df1, df2, ['Name'])

# reset index
df_final = df_final.reset_index(drop=True)

# print result

print(df_final)

    ID        Name  cluster id  confidence
0   98     1o7v9sm         0.0    1.000000
1    2     lo7v9sm         0.0    1.000000
2  175  hp. part 1         1.0    0.999999
3   12  h.p part 1         1.0    0.999999
4   56     aaeessa         2.0    0.999967
5   76     aa3esza         2.0    0.999967
6  762  stakoverfl         NaN         NaN

. Вы видите, что сопоставленным парам назначается кластер и уровень достоверности.непревзойденные nan.Теперь вы можете анализировать эту информацию по своему усмотрению.например, можно взять результаты только с уровнем достоверности выше 80%.

1 голос
/ 20 сентября 2019

Использование функции fuzzy_wuzzy из связанного ответа:

from fuzzywuzzy import fuzz
from fuzzywuzzy import process

mrg = fuzzy_merge(df1, df2, 'Name', 'Name', threshold=70)\
      .merge(df2, left_on='matches', right_on='Name', suffixes=['1', '2'])\
      .filter(like='ID')

Вывод

   ID1  ID2
0   56   76
1   98    2
2  175   12
3    2  762
0 голосов
/ 20 сентября 2019

Я предлагаю вам библиотеку под названием Python Record Linkage Toolkit.

После того, как вы импортируете библиотеку, вы должны проиндексировать источники, которые вы хотите сравнить, что-то вроде этого:

 indexer = recordlinkage.Index()

 #using url as intersection
 indexer.block('id')
 candidate_links = indexer.index(df_1, df_2)

 c = recordlinkage.Compare()

Давайтескажем, вы хотите сравнить, основываясь на одинаковых строках, но они не совпадают точно:

 c.string('name', 'name', method='jarowinkler', threshold=0.85)

И если вы хотите точное совпадение, вы должны использовать:

c.exact('name')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...