Нужна помощь в оптимизации слияния двух информационных фреймов на основе нескольких условий (по приоритету) - PullRequest
1 голос
/ 07 марта 2020

В настоящее время у меня есть сценарий, который объединяет два кадра данных на основе нескольких условий, но трудно и медленно сказать, правильно ли он объединяется. Нужна помощь в поиске более эффективного способа.

У меня есть два кадра данных, которые выглядят так:

займы

             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. Поэтому мне нужно объединить первый кадр данных со вторым на основе трех условий:

Упорядочено по приоритету:

  1. if: id == match_id
  2. еще, если: sec_id == match_sec_id
  3. еще, если: 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...