#python-3.x #pandas #max #min #timedelta
#python-3.x #pandas #макс #min #интервал времени
Вопрос:
Я хотел бы рассчитать распределение товара на основе того, сколько времени проходит между первым и последним заказом этого товара. Однако для достижения этой цели сначала я должен получить эту временную дельту для каждого элемента.
Мой исходный фрейм данных состоит из трех столбцов: «Order_ID», «Order_DATE», «Medium_ID», как показано в следующем примере:
df = pd.DataFrame({'Medium_ID': {0: '1359',
1: '1360',
2: '1359',
3: '1360',
4: '1360',
5: '1404',
6: '1381',
7: '1359',
8: '1419',
9: '1360'},
'Order_ID': {0: '1',
1: '2',
2: '3',
3: '4',
4: '5',
5: '6',
6: '7',
7: '8',
8: '9',
9: '10'},
'Order_DATE': {0: Timestamp('2008-04-21 00:00:00'),
1: Timestamp('2008-04-21 00:00:00'),
2: Timestamp('2008-04-21 00:00:00'),
3: Timestamp('2008-04-21 00:00:00'),
4: Timestamp('2008-04-22 00:00:00'),
5: Timestamp('2008-04-22 00:00:00'),
6: Timestamp('2008-04-23 00:00:00'),
7: Timestamp('2008-04-23 00:00:00'),
8: Timestamp('2008-04-23 00:00:00'),
9: Timestamp('2008-04-28 00:00:00')}}))
Поскольку у нас может быть несколько order_IDs для одного и того же medium_ID, первое, что я попытался сгруппировать по столбцу «Medium_ID», но тогда я не знаю, как развиваться.
Я хотел бы иметь новый фрейм данных с двумя столбцами: «Medium_ID» и «Days_between_the_last_and_the_first-order» и, в конце концов, показать распределение для серии «Days_between_the_last_and_the_first-order».
Ответ №1:
Вы можете рассчитать дни между первым и последним заказом для каждого элемента, например:
df.groupby('Medium_ID').Order_DATE.apply(lambda x: x.max() - x.min())
Что приводит к:
Medium_ID
1359 2 days
1360 7 days
1381 0 days
1404 0 days
1419 0 days
Комментарии:
1. Более приятное, простое и аккуратное решение по сравнению с моим :)). Конечно, чтобы поддержать это!
Ответ №2:
Для дней между последней и первой датой заказа вы можете попробовать это.
grouped = (
df.drop("Order_ID", axis=1)
.sort_values(["Medium_ID", "Order_DATE"])
.groupby("Medium_ID")
.agg(["first", "last"])
)
grouped.columns = ["first_order_date", "last_order_date"]
grouped.reset_index(inplace=True)
grouped["days_between_last_and_first_order"] = (
grouped["last_order_date"] - grouped["first_order_date"]
).dt.days
grouped = grouped[["Medium_ID", "days_between_last_and_first_order"]]
Или, используя решение @Franco, было бы,
grouped = df.groupby("Medium_ID")["Order_DATE"].apply(
lambda x: x.max() - x.min()
).to_frame().reset_index().rename(
{"Order_DATE": "days_between_last_and_first_order"}, axis=1
)
grouped["days_between_last_and_first_order"] = grouped["days_between_last_and_first_order"].dt.days
Для визуализации распределения,
grouped.hist(column="days_between_last_and_first_order")
Комментарии:
1. Спасибо! В части «показать распределение …» Я имею в виду отображение гистограммы событий для каждого timedelta. Позвольте мне объяснить: если dtype столбца сгруппирован. days_between_last_and_first_order был INT, у меня могло быть что-то вроде этого: grouped.hist(column=»days_between_last_and_first_order») , который показывает «распределение» вхождений.
2. @rafspo Я обновил свой ответ в соответствии с вашими потребностями. Итак, идея заключается в том, чтобы извлечь число из
days_between_last_and_first_order
столбца, используя.dt.days