Функция изменения дат в зависимости от периода времени?

#python #function

#питон #функция

Вопрос:

У меня есть список удостоверений личности и дат. Что я хотел бы сделать, так это установить одну и ту же дату на 2-дневный период времени. Возникли проблемы с написанием функции для этого. Это похоже на использование эквивалента SQL НАД РАЗДЕЛОМ С помощью

 Input: d1 = {'id': ['a','a','a','a','b','a','b'], 'datetime': ['10/25/2021 0:00','10/26/2021 0:00','11/28/2021 0:00','11/29/2021 0:00','11/29/2021 0:00', '11/30/2021 0:00', '11/30/2021 0:00']} df1 = pd.DataFrame(d1) df1['datetime'] = pd.to_datetime(df1['datetime'])  Desired Output: d3 = {'id': ['a','a','a','a','a','b','b'], 'datetime': ['10/25/2021 0:00','10/25/2021 0:00','11/28/2021 0:00','11/28/2021 0:00', '11/30/2021 0:00','11/29/2021 0:00','11/29/2021 0:00']} df1 = pd.DataFrame(d3)  

Решение, которое я ищу, должно группироваться по идентификатору, отсортированному по дате и времени. С первым значением даты и времени в этой группе создайте группу из всех строк в течение 2-дневного периода времени и назначьте этим строкам это первое значение даты и времени, затем перейдите к следующей дате и повторите. Затем перейдите к следующему идентификатору.

Ответ №1:

Попробуйте это:

 from datetime import datetime as dt df1.sort_values(by=['id']) oldest = {df1.iloc[0,0]: dt.strptime(df1['datetime'][0], "%m/%d/%Y %H:%M")} for t in range(df1['datetime'].shape[0]):  if df1.iloc[t,0] in oldest:  if ((dt.strptime(df1['datetime'][t],"%m/%d/%Y %H:%M") - oldest[df1.iloc[t,0]]).days) gt;1:  oldest[df1.iloc[t,0]] = dt.strptime(df1['datetime'][t], "%m/%d/%Y %H:%M")  else:  oldest[df1.iloc[t, 0]] = dt.strptime(df1['datetime'][t], "%m/%d/%Y %H:%M")  df1.iloc[t, 1] = oldest[df1.iloc[t, 0]]  

Результатом будет:

 id datetime 0 a 2021-10-25 00:00:00 1 a 2021-10-25 00:00:00 2 a 2021-11-28 00:00:00 3 a 2021-11-28 00:00:00 4 b 2021-11-29 00:00:00 5 a 2021-11-30 00:00:00 6 b 2021-11-29 00:00:00  

Комментарии:

1. Учитывает ли это идентификатор?

2. что вам нужно об удостоверении личности?

3. В вашем вопросе, желаемый вывод для идентификатора, ничего не сказал. Каков ваш желаемый идентификатор?

4. Когда идентификатор изменяется (т. е. строка со 2 на 3), функция должна начинаться сначала. Изменил ввод/желаемый вывод в вопросе, чтобы сделать его более понятным. извините

5. Я все еще не могу понять вашу точку зрения. Ваш желаемый идентификатор все тот же!

Ответ №2:

Попробуйте с groupby :

 df["datetime"] = pd.to_datetime(df["datetime"]) output = df.groupby("id").apply(lambda x: x.iloc[::2].reindex(x.index).ffill()).sort_values(["id", "datetime"])  gt;gt;gt; output   id datetime 0 a 2021-10-25 1 a 2021-10-25 2 a 2021-11-28 3 a 2021-11-28 5 a 2021-11-30 4 b 2021-11-29 6 b 2021-11-29  

Комментарии:

1. Таким образом, это проверяет каждые 2 строки. Я хочу, чтобы все начиналось сначала для каждого удостоверения личности. Таким образом, индекс 3 не должен меняться на основе индекса 2, потому что идентификатор индекса 3-b, а индекс 2-a. Как мы можем это изменить?

2. @chicagobeast12 — Отредактировано. Просто к вашему сведению, это решение намного быстрее, чем зацикливание на фрейме данных.

3. Проблема в том, что вы предполагаете, что мое 2-дневное окно означает, что у меня может быть только 2 строки в одной группе, т. Е. (10/25, 10/26). Это не сработает, если бы у меня было (10/25, 10/26, 10/26) в группе. Результатом вашего решения будет (10/25, 10/25, 10/26). Если у вас есть однозначное решение для этого… с удовольствием бы им воспользовался, но если нет, то не беспокойтесь

4. Каким должен быть ваш результат за 10/25, 10/25, 10/26? Я думал, вы имели в виду, что хотите заполнить вперед каждые две строки. Вот почему вам нужно более четко объяснить свой вопрос в ОП и включить все такие случаи.

5. Я сказал 2-дневный период времени, а не 2 последовательные строки. И в ОП я четко заявил, что он должен продолжать оценивать один и тот же идентификатор до тех пор, пока не закончится это 2-дневное окно. Я понимаю, что это сложное решение, которое я ищу, но старался сделать все возможное, чтобы сформулировать проблему