Ответ первой части соответствует только dupes No
столбцы, если они не существуют Yes
строки:
df['Raised_Date'] = pd.to_datetime(df['Raised_Date'])
df1 = df[df.drop(['Duplicate','Iss_id'], 1).duplicated(keep=False)]
mask = (df1.assign(Duplicate = df1['Duplicate'].eq('No'))
.groupby(df1.columns.difference(['Duplicate','Iss_id']).tolist())['Duplicate']
.transform('all'))
df1 = df1[mask]
print (df1)
Iss_id Ins_ID XY Duplicate Raised_Date Type
4 5 2 (2,5) No 2019-10-07 10:29:50 A
5 6 2 (2,5) No 2019-10-07 10:29:50 A
Для следующих двух решений используется merge_asof
функция с возможным допуском параметр и проверка тех же столбцов по параметру by
:
df21 = df[df['Duplicate'].eq('No')].sort_values('Raised_Date').copy()
df22 = df1.drop_duplicates().sort_values('Raised_Date').copy()
#print (df21)
#print (df22)
df2 = (pd.merge_asof(df21, df22,
on='Raised_Date',
by=['Ins_ID','XY','Type'],
tolerance=pd.Timedelta(5 * 60, unit='s'),
direction='forward',
suffixes=('','_'))
.dropna(subset=['Duplicate_'])
.drop(['Duplicate_','Iss_id_'], axis=1))
print (df2)
Iss_id Ins_ID XY Duplicate Raised_Date Type
0 3 2 (2,5) No 2019-10-07 10:27:50 A
3 5 2 (2,5) No 2019-10-07 10:29:50 A
4 6 2 (2,5) No 2019-10-07 10:29:50 A
Аналогичное решение, требуется только direction='forward'
и direction='backward'
(значение по умолчанию, поэтому не указывается), объединение столбцов и фильтрация пропущенных строк:
df31 = (pd.merge_asof(df21, df22,
on='Raised_Date',
by=['XY','Type'],
tolerance=pd.Timedelta(120 * 60, unit='s'),
direction='forward',
suffixes=('','_'))
)
df32 = (pd.merge_asof(df21, df22,
on='Raised_Date',
by=['XY','Type'],
tolerance=pd.Timedelta(120 * 60, unit='s'),
suffixes=('','_'))
)
df3 = df21[df31['Duplicate_'].fillna(df32['Duplicate_']).notna().to_numpy()]
print (df3)
Iss_id Ins_ID XY Duplicate Raised_Date Type
2 3 2 (2,5) No 2019-10-07 10:27:50 A
4 5 2 (2,5) No 2019-10-07 10:29:50 A
5 6 2 (2,5) No 2019-10-07 10:29:50 A
6 7 3 (2,5) No 2019-10-07 11:27:50 A