Как можно улучшить код обработки данных?
Есть набор данных с 3 колонками : REV_NUM_CL, ID_COMMS, ,DT_CONTACT.
Надо выбрать только те данные (значения: REV_NUM_CL, ID_COMMS), которые удовлетворяют любому из условий:
- В группировке по
REV_NUM_CLесть только одинID_COMMSс заполненнымиDT_CONTACT. - В группировке по
REV_NUM_CLесть только один уникальныйID_COMMS.
Общая цель в том, чтобы найти для каждого REV_NUM_CL найти уникальный ID_COMMS, если это возможно.
Я смог решить эту задачу, однако мое решение кажется мне далеким от идеального.
Думаю, можно проще, короче и понятнее. Помогите упростить.
Мой код:
import pandas as pd
data = [
{'REV_NUM_CL': 1, 'ID_COMMS': 11, 'DT_CONTACT': 111},
{'REV_NUM_CL': 1, 'ID_COMMS': 12, 'DT_CONTACT': 122},
{'REV_NUM_CL': 2, 'ID_COMMS': 21, 'DT_CONTACT': None},
{'REV_NUM_CL': 2, 'ID_COMMS': 22, 'DT_CONTACT': None},
{'REV_NUM_CL': 3, 'ID_COMMS': 31, 'DT_CONTACT': 311},
{'REV_NUM_CL': 3, 'ID_COMMS': 32, 'DT_CONTACT': 321},
{'REV_NUM_CL': 3, 'ID_COMMS': 33, 'DT_CONTACT': 331},
{'REV_NUM_CL': 3, 'ID_COMMS': 33, 'DT_CONTACT': 332},
{'REV_NUM_CL': 3, 'ID_COMMS': 34, 'DT_CONTACT': None},
{'REV_NUM_CL': 4, 'ID_COMMS': None, 'DT_CONTACT': None},
{'REV_NUM_CL': 5, 'ID_COMMS': 51, 'DT_CONTACT': 511},
{'REV_NUM_CL': 5, 'ID_COMMS': 52, 'DT_CONTACT': None},
{'REV_NUM_CL': 6, 'ID_COMMS': 61, 'DT_CONTACT': None}
]
# Группа 1 не подходит, т.к. есть два разных ID_COMMS и у обоих заполнен DT_CONTACT
# Группа 2 не подходит, т.к есть два разных ID_COMMS и у обоих не заполнен DT_CONTACT
# Группа 3 не подходит, так как есть больше одного ID_COMMS и которых заполнен DT_CONTACT
# Группа 4 не подходит, т.к. ID_COMMS нет вообще
# Группа 5 подходит, так как есть только один ID_COMMS у которго заполнен DT_CONTACT
# Группа 6 подходит, так как есть всего один ID_COMMS
df = pd.DataFrame(data)
# Посчитать уникальное значение ID_COMMS, где заполнен DT_CONTACT в группах
df_cnt = df[df['DT_CONTACT'].notnull()].groupby('REV_NUM_CL')[['ID_COMMS']].nunique()
df_cnt.columns = ['CNT']
# Посчитать уникальное значение ID_COMMS, вообще
df_cnt_u = df.groupby('REV_NUM_CL')[['ID_COMMS']].nunique()
df_cnt_u.columns = ['CNT_U']
# И объединить в массив обратно
df = pd.merge(df, df_cnt, on='REV_NUM_CL', how='left')
df['CNT'].fillna(0, inplace=True)
df = pd.merge(df, df_cnt_u, on='REV_NUM_CL', how='left')
df['CNT_U'].fillna(0, inplace=True)
df['FIRST'] = ( ( df['CNT'] == 1 )
& ( df['DT_CONTACT'].notnull() )
& ( df['ID_COMMS'].notnull() )
).astype(int)
df['SECOND'] = ( ( df['CNT_U'] == 1 )
& ( df['ID_COMMS'].notnull() )
).astype(int)
# Итог:
df_res = df[(df['FIRST'] == 1) | (df['SECOND'] == 1) ][['ID_COMMS', 'REV_NUM_CL']].drop_duplicates() # перестраховался