Мне нужно создать уникальное поле «ID» для моих строк Pandas на основе определенных условий, связанных с предыдущими строками.
Ниже вы увидите образец моих данных:
current_driver customer_id pu_actual_dt service
0 167 1214 2018-06-28 13:24:00 DED
1 167 1214 2018-06-28 13:25:00 DED
2 167 1214 2018-06-28 14:43:00 DED
3 243 1214 2018-06-28 19:41:00 DED
4 243 1214 2018-06-28 19:41:00 DED
5 250 1214 2018-06-28 17:19:00 DED
6 250 1214 2018-06-28 18:00:00 DED
7 250 1214 2018-06-28 18:18:00 DED
8 259 1214 2018-06-28 19:40:00 DED
9 259 1214 2018-06-28 19:40:00 DED
10 259 1214 2018-06-28 20:14:00 DED
11 260 1214 2018-06-28 17:39:00 DED
12 260 1214 2018-06-28 17:39:00 DED
13 260 1214 2018-06-28 17:39:00 DED
14 260 1214 2018-06-28 17:39:00 DED
15 263 1214 2018-06-28 18:34:00 DED
16 263 1214 2018-06-28 18:43:00 DED
17 263 1214 2018-06-28 18:43:00 DED
Что мне нужно сделать, это создать еще один столбец со следующей логикой: если current_driver такой же, как current_driver предыдущей строки, И customer_id такой же, как customer_id предыдущей строки И pu_actual_dt находится в пределах половины час предыдущего ряда, тогда он должен иметь одинаковый идентификатор. Таким образом, он будет начинаться с «1» для первых двух строк, но, поскольку третий ряд pu_actual_dt более чем через полчаса, он будет иметь идентификатор «2». Тогда четвертый ряд имеет другой драйвер, поэтому он будет иметь идентификатор «3» вместе со строкой № 5, поскольку он имеет тот же драйвер / customer_id / pu_actual_dt, что и строка № 4.
До того, как я учел незначительные различия в pu_actual_dt (см. Первые две строки), я смог решить эту проблему путем объединения полей и запуска нового идентификатора каждый раз, когда строка не совпадала с предыдущей конкатенацией. Так, например, я использовал это для создания идентификатора раньше:
df = df.assign(id=(df['route_concate']).astype('category').cat.codes)
Однако эта логика конкатенации не работает, когда у меня есть небольшие различия в pu_actual_dt.
Поэтому я попытался учесть незначительные изменения во времени, выполнив следующее:
df['id'] = np.where((df['current_driver'] == df['current_driver'].shift(1) )
& (df['customer_id'] == df['customer_id'].shift(1))
& (df['pu_actual_dt'] < df['pu_actual_dt'].shift(1) + pd.Timedelta(minutes=30))
& (df['pu_actual_dt'] > df['pu_actual_dt'].shift(1) - pd.Timedelta(minutes=30))
& (df['service'] == 'DED'), df['id'].shift(1), df['id'].shift(1) + 1)
То, что я пытаюсь сделать здесь, это сказать для каждой строки, если current_driver = current_driver в строке выше и customer_id = customer_id в строке выше, pu_actual_dt в течение 30 минут до или после pu_actual_dt в предыдущей строке и service = ' DED ', затем используйте идентификатор предыдущего ряда. Если нет, то добавьте 1 к идентификатору предыдущей строки.
Я не уверен, что я делаю неправильно, но это возвращает очень непредсказуемые результаты. В какой-то момент он падает с ID 75 до 34, а затем обратно до 36?
Как лучше решить мою проблему? (Также тот, где идентификатор будет начинаться с «1»). Спасибо за вашу помощь, как всегда!