Как найти количество дней до нужной даты?
Дан df:
a = pd.DataFrame([{'id': 1, 'b': 1, 'd': 18.12.12},
{'id': 1, 'b': 2, 'd': 15.12.12},
{'id': 1, 'b': 2, 'd': 14.12.12},
{'id': 1, 'b': 2, 'd': 12.12.12},
{'id': 1, 'b': 4, 'd': 12.12.12},
{'id': 2, 'b': 1, 'd': 19.12.12},
{'id': 2, 'b': 2, 'd': 17.12.12},
{'id': 2, 'b': 2, 'd': 15.12.12},
{'id': 2, 'b': 2, 'd': 12.12.12},
{'id': 2, 'b': 3, 'd': 12.12.12},
{'id': 3, 'b': 1, 'd': 17.12.12},
{'id': 3, 'b': 2, 'd': 16.12.12},
{'id': 3, 'b': 2, 'd': 15.12.12},
{'id': 3, 'b': 2, 'd': 14.12.12},
{'id': 3, 'b': 6, 'd': 12.12.12}])
Как можно сгруппировать строки по значению id и по значению b, например равного 2, и по значениям в столбце d определить наименьшее прошедшее количество дней до даты в столбце d, того же id, но b == 1, занести в столбец k?
То есть должно получиться:
pd.DataFrame([{'id': 1, 'b': 1, 'd': 18.12.12, 'k': 3},
{'id': 1, 'b': 2, 'd': 15.12.12, 'k': 3},
{'id': 1, 'b': 2, 'd': 14.12.12, 'k': 3},
{'id': 1, 'b': 2, 'd': 12.12.12, 'k': 3},
{'id': 1, 'b': 4, 'd': 12.12.12, 'k': 3},
{'id': 2, 'b': 1, 'd': 19.12.12, 'k': 2},
{'id': 2, 'b': 2, 'd': 17.12.12, 'k': 2},
{'id': 2, 'b': 2, 'd': 15.12.12, 'k': 2},
{'id': 2, 'b': 2, 'd': 12.12.12, 'k': 2},
{'id': 2, 'b': 3, 'd': 12.12.12, 'k': 2},
{'id': 3, 'b': 1, 'd': 17.12.12, 'k': 1},
{'id': 3, 'b': 2, 'd': 16.12.12, 'k': 1},
{'id': 3, 'b': 2, 'd': 15.12.12, 'k': 1},
{'id': 3, 'b': 2, 'd': 14.12.12, 'k': 1},
{'id': 3, 'b': 6, 'd': 12.12.12, 'k': 1}])
Предполагаю, что логика решения этой проблемы такая:
мы создаем столбец g по сгруппированным значениям по id и b == 1, добавив в него значения из d
далее группируем также по id, но уже по b == 2
далее из значения в столбце g вычитаем выше сгруппированные значение в d (дата в столбце g всегда будет позднее)
далее выбираем из них минимальное и заносим в столбец k
Возможно есть и более быстрый путь.
Ответы (3 шт):
на самом деле всё очень просто, но этот способ легче чем твой! #для начала импортируем модуль datetime
from datetime import datetime, date, time
#далее пишем код!
now = datetime.today() #Это будет наша дата, вводить сюда ничего не нужно
NY = datetime(2022,1,2) #Эта же строка отвечает за дату до которой нам нужно считать,
в примере новый год
d = NY-now #данная строка считает время до даты которую мы указали в строчке NY
#теперь принтуем!
print("До нового года:", d.days ,"день|дней!")
#на выходе получаем ответ:
До нового года: 294 день|дней!
Мне не очень нравится это решения ввиду отсутствия изящества, но, тем не менее:
df["k"] =df[df["b"]==1].groupby("id")["d"].transform("first")
df["k"] = df["k"].fillna(method="ffill").dt.day - df["d"].dt.day
df["k"] = df.groupby("id")["k"].transform(lambda x: x[x.ne(0)].min())
df:
id b d k
0 1 1 2012-12-18 3
1 1 2 2012-12-15 3
2 1 2 2012-12-14 3
3 1 2 2012-12-12 3
4 1 4 2012-12-12 3
5 2 1 2012-12-19 2
6 2 2 2012-12-17 2
7 2 2 2012-12-15 2
8 2 2 2012-12-12 2
9 2 3 2012-12-12 2
10 3 1 2012-12-17 1
11 3 2 2012-12-16 1
12 3 2 2012-12-15 1
13 3 2 2012-12-14 1
14 3 6 2012-12-12 1
days = ((a.query("b == 1").groupby("id")["d"].min()
-
a.query("b == 2").groupby("id")["d"].max()
).dt.days.reset_index(name="k"))
res = a.merge(days, how="left")
результат:
In [67]: res
Out[67]:
id b d k
0 1 1 2012-12-18 3
1 1 2 2012-12-15 3
2 1 2 2012-12-14 3
3 1 2 2012-12-12 3
4 1 4 2012-12-12 3
5 2 1 2012-12-19 2
6 2 2 2012-12-17 2
7 2 2 2012-12-15 2
8 2 2 2012-12-12 2
9 2 3 2012-12-12 2
10 3 1 2012-12-17 1
11 3 2 2012-12-16 1
12 3 2 2012-12-15 1
13 3 2 2012-12-14 1
14 3 6 2012-12-12 1