У меня есть две очень большие таблицы df1 и df2 (по несколько миллионов строк в каждой), относящиеся к человеку, и в каждой таблице есть столбец, содержащий имя человека (имя столбца: «Имя»). Имена одного и того же человека могут быть написаны по-разному (например, «Джефф МакГрегор» или «Мистер Дж. МакГрегор» и т. Д.) В двух таблицах, поэтому я хочу применить нечеткое сопоставление строк с пакетом fuzzywuzzy в Python(это просто сравнивает две строки и возвращает меру сходства).
В качестве выходных данных (см. Df3 для желаемой выходной таблицы), я хотел бы заполнить столбцы «Match_Flag» и «Match_List» в df1 в соответствии с записями в df2. Для каждого (уникального) человека в df1 я хочу проверить, есть ли совпадения (нечеткая строка) в df2. Если есть строка, столбец «Match_Flag» должен содержать «да», а если нет - «нет». Столбец «Match_list» должен содержать для каждого имени список совпадений. Если есть одно совпадение, список будет содержать одну запись, а если будет, например, три совпадения, список будет содержать 3 совпадения. Если совпадений нет, список должен быть просто пустым.
Это данные:
df1
data_df1 = {'ID':[56382, 34732, 12423, 29574, 76532],
'Name':['Tom Hilley', 'Andreas Puthz', 'Jeff McGregor', 'Jack Ebbstein', 'Lisa Norwat'],
'Match_Flag':["", "", "", "", ""],
'Match_List':["", "", "", "", ""]}
df1 = pd.DataFrame(data_df1)
print(df1)
ID Name Match_Flag Match_List
0 56382 Tom Hilley
1 34732 Andreas Puthz
2 12423 Jeff McGregor
3 29574 Jack Ebbstein
4 76532 Lisa Norwat
df2
data_df2 = {'Name':['Tom Hilley', 'Madalina Peter', 'Russel Cross', 'Jenni Pey', 'Kanush Hawks', 'Mr. J McGregor', 'Ebbstein Jack', 'Mr. Jack Ebbstein'],
'Age':[16, 56, 33, 44, 24, 26, 86, 32]}
df2 = pd.DataFrame(data_df2)
print(df2)
Name Age
0 Tom Hilley 16
1 Madalina Peter 56
2 Russel Cross 33
3 Jenni Pey 44
4 Kanush Hawks 24
5 Mr. J McGregor 26
6 Ebbstein Jack 86
7 Mr. Jack Ebbstein 32
df3
data_df3 = {'ID':[56382, 34732, 12423, 29574, 76532],
'Name':['Tom Hilley', 'Andreas Puthz', 'Jeff McGregor', 'Jack Ebbstein', 'Lisa Norwat'],
'Match_Flag':["yes", "no", "yes", "yes", "no"],
'Match_List':[["Tom Hilley"], [], ["Mr. J McGregor"], ["Ebbstein Jack","Mr. Jack Ebbstein"], []]}
df3 = pd.DataFrame(data_df3)
print(df3)
ID Name Match_Flag Match_List
0 56382 Tom Hilley yes [Tom Hilley]
1 34732 Andreas Puthz no []
2 12423 Jeff McGregor yes [Mr. J McGregor]
3 29574 Jack Ebbstein yes [Ebbstein Jack, Mr. Jack Ebbstein]
4 76532 Lisa Norwat no []
Мой подход:
# import libraries
import pandas as pd
from fuzzywuzzy import fuzz
# create matching
for i in df1["Name"].unique().tolist():
# initialize matching list
matching_list = []
for j in df2["Name"].unique().tolist():
# create matching score
if fuzz.token_set_ratio(i, j) >= 90:
matching_list.append(j)
# create red flags
if matching_list:
df1.loc[df1['Name'] == i,'Match_Flag'] = 'yes'
df1.loc[df1['Name'] == i,'Match_List'] = matching_list
else:
df1.loc[df1['Name'] == i,'Match_Flag'] = 'no'
df1.loc[df1['Name'] == i,'Match_List'] = ["-"]
Вывод моего подхода:
line 611, in _setitem_with_indexer
raise ValueError('Must have equal len keys and value '
ValueError: Must have equal len keys and value when setting with an iterable
Поскольку мой подход 1. не работает, а 2. он будет слишком медленным для миллионов строк , прошу вас помочь мне и, пожалуйста, найти более эффективный и работающий подход.