Нечеткое слияние / совпадение Python Pandas с дубликатами
У меня есть 2 кадра данных, 1 для доноров и 1 для сборщиков средств. В идеале, что яЯ пытаюсь выяснить, делали ли какие-либо сборщики денег пожертвования, и если это так, скопируйте часть этой информации в мой набор данных по сбору средств (имя донора, электронная почта и их первое пожертвование). Проблемы с моими данными: 1) Мне нужно сопоставить по имени и электронной почте, но у пользователя могут быть несколько разные имена (например, Кэт и Кэти). 2) Дубликаты имен для доноров и сборщиков средств. 2a) С донорами я могу получить уникальные комбинации имя / адрес электронной почты, так как я забочусь о дате первого пожертвования. 2b) С сборщиками денег, хотя мне нужно сохранить обе строки и не потерять данные, такие как дата.
Пример кода у меня сейчас:
import pandas as pd
import datetime
from fuzzywuzzy import fuzz
import difflib
donors = pd.DataFrame({"name": pd.Series(["John Doe","John Doe","Tom Smith","Jane Doe","Jane Doe","Kat test"]), "Email": pd.Series(['[email protected]','[email protected]','[email protected]','[email protected]','[email protected]','[email protected]']),"Date": (["27/03/2013 10:00:00 AM","1/03/2013 10:39:00 AM","2/03/2013 10:39:00 AM","3/03/2013 10:39:00 AM","4/03/2013 10:39:00 AM","27/03/2013 10:39:00 AM"])})
fundraisers = pd.DataFrame({"name": pd.Series(["John Doe","John Doe","Kathy test","Tes Ester", "Jane Doe"]),"Email": pd.Series(['[email protected]','[email protected]','[email protected]','[email protected]','[email protected]']),"Date": pd.Series(["2/03/2013 10:39:00 AM","27/03/2013 11:39:00 AM","3/03/2013 10:39:00 AM","4/03/2013 10:40:00 AM","27/03/2013 10:39:00 AM"])})
donors["Date"] = pd.to_datetime(donors["Date"], dayfirst=True)
fundraisers["Date"] = pd.to_datetime(donors["Date"], dayfirst=True)
donors["code"] = donors.apply(lambda row: str(row['name'])+' '+str(row['Email']), axis=1)
idx = donors.groupby('code')["Date"].transform(min) == donors['Date']
donors = donors[idx].reset_index().drop('index',1)
Таким образом, это оставляет мне первое пожертвование от каждого донора (при условии, что любой человек с таким же именем и адресом электронной почты будет одним и тем же человеком).
в идеале я хочу, чтобы мой набор данных по сбору средств выглядел так:
Date Email name Donor Name Donor Email Donor Date
2013-03-27 10:00:00 [email protected] John Doe John Doe [email protected] 2013-03-27 10:00:00
2013-01-03 10:39:00 [email protected] John Doe John Doe [email protected] 2013-03-27 10:00:00
2013-02-03 10:39:00 [email protected] Kathy test Kat test [email protected] 2013-03-27 10:39:00
2013-03-03 10:39:00 [email protected] Tes Ester
2013-04-03 10:39:00 [email protected] Jane Doe Jane Doe [email protected] 2013-04-03 10:39:00
Я пытался следовать этой теме:Можно ли сделать слияние нечетких совпадений с питонами пандами? но продолжайте получать индекс из ошибок диапазона (догадываясь, что это не 'мне не нравятся повторяющиеся имена в сборщиках денег) :( Так есть идеи, как я могу сопоставить / объединить эти наборы данных?
делать это с помощью циклов for (что работает, но очень медленно, и я чувствую, что должен быть лучший способ)
fundraisers["donor name"] = ""
fundraisers["donor email"] = ""
fundraisers["donor date"] = ""
for donindex in range(len(donors.index)):
max = 75
for funindex in range(len(fundraisers.index)):
aname = donors["name"][donindex]
comp = fundraisers["name"][funindex]
ratio = fuzz.ratio(aname, comp)
if ratio > max:
if (donors["Email"][donindex] == fundraisers["Email"][funindex]):
ratio *= 2
max = ratio
fundraisers["donor name"][funindex] = aname
fundraisers["donor email"][funindex] = donors["Email"][donindex]
fundraisers["donor date"][funindex] = donors["Date"][donindex]