Удаление дубликатов на основе ближайшего условия Datetime - PullRequest
0 голосов
/ 16 июня 2020
import pandas as pd

def nearest(items, pivot):
    return min(items, key=lambda x: abs(x - pivot))

df = pd.read_csv("C:/Files/input.txt", dtype=str)
duplicatesDf = df[df.duplicated(subset=['CLASS_ID', 'START_TIME', 'TEACHER_ID'], keep=False)]
duplicatesDf['START_TIME'] =  pd.to_datetime(duplicatesDf['START_TIME'], format='%Y/%m/%d %H:%M:%S.%f')
print duplicatesDf
print df['START_TIME'].dt.date

df:
ID,CLASS_ID,START_TIME,TEACHER_ID,END_TIME
1,123,2020/06/01 20:47:26.000,o1,2020/06/02 00:00:00.000
2,123,2020/06/01 20:47:26.000,o1,2020/06/04 20:47:26.000
3,789,2020/06/01 20:47:26.000,o3,2020/06/03 14:47:26.000
4,789,2020/06/01 20:47:26.000,o3,2020/06/03 14:40:00.000
5,456,2020/06/01 20:47:26.000,o5,2020/06/08 20:00:26.000

Итак, у меня есть фрейм данных, как указано выше. Как видите, у меня есть несколько записей с одинаковыми CLASS_ID,START_DATE и TEACHER_ID. Всякий раз, когда присутствует несколько таких записей, я хотел бы сохранить только 1 запись при условии, что сохраняемая запись должна иметь END_DATE ближайшую к START_DATE (с точностью до минут) .

В этом случае для CLASS_ID 123 будет сохранена запись с ID 1, поскольку ее END_DATE 2020/06/02 00:00:00.000 ближе всего к START_DATE 2020/06/01 20:47:26.000 по сравнению с записью с ID 2, чей END_DATE is 2020/06/04 20:47:26.000. Аналогично для CLASS_ID 789, запись с ID 4 будет сохранена.

Следовательно, ожидаемый результат будет:

ID,CLASS_ID,START_TIME,TEACHER_ID,END_TIME
1,123,2020/06/01 20:47:26.000,o1,2020/06/02 00:00:00.000
4,789,2020/06/01 20:47:26.000,o3,2020/06/03 14:40:00.000
5,456,2020/06/01 20:47:26.000,o5,2020/06/08 20:00:26.000

Я просматривал следующие ссылки, { ссылка }, { ссылка }, чтобы найти решение, но, к сожалению, зашли в тупик.

Следовательно, какой-то разум души поможет мне немного. Большое спасибо.

1 Ответ

0 голосов
/ 16 июня 2020

IIU C, мы можем использовать .loc и idxmin() после создания условного столбца для измерения времени, прошедшего между началом и концом, мы применим idxmin() как групповую операцию к вашему CLASS_ID столбец.

df.loc[
    df.assign(mins=(df["END_TIME"] - df["START_TIME"]))
    .groupby("CLASS_ID")["mins"]
    .idxmin()
]


   ID  CLASS_ID          START_TIME TEACHER_ID            END_TIME
0   1       123 2020-06-01 20:47:26         o1 2020-06-02 00:00:00
4   5       456 2020-06-01 20:47:26         o5 2020-06-08 20:00:26
3   4       789 2020-06-01 20:47:26         o3 2020-06-03 14:40:00

с шагом.

Time Delta.

print(df.assign(mins=(df["END_TIME"] - df["START_TIME"]))[['CLASS_ID','mins']])

   CLASS_ID            mins
0       123 0 days 03:12:34
1       123 3 days 00:00:00
2       789 1 days 18:00:00
3       789 1 days 17:52:34
4       456 6 days 23:13:00

минимальный индекс из столбца временной дельты при группировке с помощью CLASS_ID

print(df.assign(mins=(df["END_TIME"] - df["START_TIME"]) )
    .groupby("CLASS_ID")["mins"]
    .idxmin())

CLASS_ID
123    0
456    4
789    3
Name: mins, dtype: int64
...