Сопоставить столбцы имени фрейма данных pandas со столбцами другого фрейма данных?

Я очень новичок в Python. Как я могу сопоставить один текстовый фрейм данных с другим? (пожалуйста, отредактируйте этот вопрос, если я задам это неправильно)

Например, учитывая эти входные данные:

 df1 =
          id  Names 
        0 123 Simpson J.
        1 456 Snoop Dogg

 df2 =
            Names 
         0  John Simpson
         1  Snoop Dogg
         2  S. Dogg
         3  Mr Dogg

Есть ли способ, который я мог бы найти (возможно, используя findall или match или любые пакеты python), чтобы я мог указать, сколько раз появлялись имена с идентификатором, что почти похоже на этот результат:

result = 
              id  Names_appeared 
            0 123   1 
            1 456   3

Ищу краткое объяснение и некоторый URL, чтобы помочь мне понять.


person Ralph Deint    schedule 20.05.2016    source источник
comment
Можете ли вы объяснить result, как вы не объяснили, как Names сопоставляются друг с другом, поскольку похоже, что вы выполняете какое-то нечеткое сопоставление или просто сопоставляете любое слово в df1 в любых словах в Names столбце в df2?   -  person EdChum    schedule 20.05.2016
comment
@EdChum Я пытаюсь увидеть, если есть какое-то совпадение, может быть, с совпадением более 70%, как у Снуп Догга из «df1», почти на 80% совпадает с С. Доггом из «df2» и мистером Доггом, мы можем удалить мистера Догга. который останется только с Доггом, который на 70% совпадает со Snoop Dogg 'df1'   -  person Ralph Deint    schedule 20.05.2016
comment
Опять же, что определяет совпадение 70/80%? Сходство Жаккара? символ% совпадения, расстояние Левенштейна? и т. д., вам нужно объяснить лучше   -  person EdChum    schedule 20.05.2016
comment
Для начала неплохо было бы взглянуть на fuzzywuzzy модуль Python.   -  person IanS    schedule 20.05.2016
comment
@EdChum Я не знаю, как объяснить фактический процент, но, глядя на фрейм данных, я только что дал вам приблизительный процент сходства данных. Кстати, не могли бы вы кратко объяснить/предоставить URL-адрес жаккарда, символа% соответствия и т. д. Чтобы я мог разобраться в этом и иметь представление о том, как уточнить этот вопрос. Нечеткое сопоставление кажется хорошим модулем, но я также хочу узнать ваше мнение об этом. Большое спасибо.   -  person Ralph Deint    schedule 20.05.2016
comment
Вы имеете в виду сравнить кадры данных на равенство? Вы хотите только сравнить их форму и значения или также типы данных каждого столбца (например, строка '123' != целое число '123' или число с плавающей запятой '123') , а также имена столбцов? Вы хотите грубое сравнение или точное сравнение? то есть может ли он потерпеть неудачу, если есть несколько дополнительных строк? даже содержащие NA/NaN/NaT? или категориальные уровни, которые отсутствуют в первом кадре данных? повторяющиеся строки? и т. д.   -  person smci    schedule 05.03.2020
comment
В вашем примере вы не сравниваете весь фрейм данных df1 с df2. Вы сравниваете только столбец df1['Names'] с df2['Names'] нормализованным способом с учетом дублирования; вам нужно нормализовать John Simpson до Simpson J.; вы просто предполагаете, что имя-фамилия взаимозаменяемы? Кроме того, вы выбрасываете столбцы идентификаторов.   -  person smci    schedule 05.03.2020


Ответы (1)


Вот пример использования fuzzywuzzy, предложенный IanS:

import pandas as pd
from fuzzywuzzy import fuzz


def fuzz_count(shortList, longList, minScore):
    """ Count fuzz ratios greater than or equal to a minimum score. """
    results = []
    for s in shortList:
        scores = [fuzz.ratio(s, l) for l in longList]
        count = sum(x >= minScore for x in scores)
        results.append(count)
    return results


data1 = {'id': pd.Series([123, 456]),
         'Names': pd.Series(['Simpson J.', 'Snoop Dogg'])}
data2 = {'Names': pd.Series(['John Simpson', 'Snoop Dogg', 'S. Dogg', 'Mr Dogg'])}
df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data2)

result = pd.DataFrame()
result['id'] = df1['id']
counts = fuzz_count(df1['Names'], df2['Names'], minScore=60)  # [1, 2]
result['Names_appeared'] = counts

print(result)  #     id  Names_appeared
               # 0  123               1
               # 1  456               2
person brennan    schedule 02.09.2016