В настоящее время у меня есть сценарий, который объединяет два кадра данных на основе нескольких условий, но трудно и медленно сказать, правильно ли он объединяется. Нужна помощь в поиске более эффективного способа.
У меня есть два кадра данных, которые выглядят так:
займы
coemail email id sec_id
0 jd@gmail.com 1 AR001
1 paul@gmail.com NaN AR002
2 peter@hotmail.com NaN AR003
3 toto@gmail.com toto@gmail.com NaN AR004
4 NaN AR006
5 deborah@gmail.com NaN AR007
::::
ведет
datetime email_stated match_id match_sec_id
0 date jd@gmail.com 1
1 date paul@gmail.com 2
2 date jd@gmail.com 3 AR003
3 date toto@gmail.com 4
4 date toto@gmail.com 5
5 date deborah@gmail.com 6
Мне нужно, чтобы ссуды соответствовали данному ведению match_id. Поэтому мне нужно объединить первый кадр данных со вторым на основе трех условий:
Упорядочено по приоритету:
- if: id == match_id
- еще, если: sec_id == match_sec_id
- еще, если: email == email_stated или coemail == email_stated
Это мой результат. Примечание. Иногда они не совпадают, а иногда возвращаются дубликаты (т. Е. Кредит, сопоставленный двум лидам с одним и тем же адресом электронной почты). Ожидается, что нужно просто убедиться, что те, которые должны соответствовать, действительно соответствуют.
index coemail email id sec_id datetime email_stated match_id match_sec_id
0 0 jd@gmail.com 1 AR001 date jd@gmail.com 1
1 2 jd@gmail.com 1 AR001 date jd@gmail.com 3 AR003
2 3 paul@gmail.com NaN AR002 date paul@gmail.com 2
3 1 peter@hotmail.com NaN AR003 date jd@gmail.com 3 AR003
4 4 toto@gmail.com toto@gmail.com NaN AR004 date toto@gmail.com 4
5 5 toto@gmail.com toto@gmail.com NaN AR004 date toto@gmail.com 5
6 4 NaN AR006 NaN NaN NaN NaN
7 6 deborah@gmail.com NaN AR007 date deborah@gmail.com 6
Это мой текущий код:
import pandas as pd
import numpy as np
los = [
{"id": 1, "sec_id": 'AR001', "email": 'jd@gmail.com', 'coemail': ''},
{"id": None, "sec_id": 'AR002', "email": 'paul@gmail.com', 'coemail': ''},
{"id": None, "sec_id": 'AR003', "email": '', 'coemail': 'peter@hotmail.com'},
{"id": None, "sec_id": 'AR004', "email": 'toto@gmail.com', 'coemail': 'toto@gmail.com'},
{"id": None, "sec_id": 'AR006', "email": '', 'coemail': ''},
{"id": None, "sec_id": 'AR007', "email": 'deborah@gmail.com', 'coemail': ''}
]
lead = [
{"match_id": 1, "match_sec_id": '', "email_stated": 'jd@gmail.com', 'datetime': 'date'},
{"match_id": 2, "match_sec_id": '', "email_stated": 'paul@gmail.com', 'datetime': 'date'},
{"match_id": 3, "match_sec_id": 'AR003', "email_stated": 'jd@gmail.com', 'datetime': 'date'},
{"match_id": 4, "match_sec_id": '', "email_stated": 'toto@gmail.com', 'datetime': 'date'},
{"match_id": 5, "match_sec_id": '', "email_stated": 'toto@gmail.com', 'datetime': 'date'},
{"match_id": 6, "match_sec_id": '', "email_stated": 'deborah@gmail.com', 'datetime': 'date'}
]
los_df = pd.DataFrame(los).astype({"id": "Int64"})
lead_df = pd.DataFrame(lead).astype({"match_id": "Int64"})
print(los_df)
print(lead_df)
match = pd.concat([
pd.merge(los_df, lead_df, how='left', left_on='id', right_on='match_id'),
pd.merge(los_df, lead_df, how='left', left_on='sec_id', right_on='match_sec_id'),
pd.merge(los_df, lead_df, how='left', left_on='email', right_on='email_stated'),
pd.merge(los_df, lead_df, how='left', left_on='coemail', right_on='email_stated')
])
conditions = [
(match['id'] == match['match_id']),
(match['sec_id'] == match['match_sec_id']),
(match['email'] == match['email_stated']) | (match['coemail'] == match['email_stated'])
]
choices = [3, 2, 1]
match['is_match'] = np.select(conditions, choices, default=0)
print(match.sort_values('is_match', ascending=False))
matches = match[match['is_match'] != 0]
matches = matches.sort_values('is_match', ascending=False).drop_duplicates(['sec_id', 'match_id']).reset_index(drop=True)
no_matches = match[match['is_match'] == 0]
no_matches = no_matches[(no_matches['sec_id'].isin(list(matches['sec_id']))) == False].drop_duplicates('sec_id')
final_df = matches.append(no_matches).sort_values('sec_id').drop('is_match', 1).reset_index(drop=False)
print(final_df)