Я хочу иметь возможность группировать свои данные по пользователю, а затем по определенным периодам дат, чтобы получить подсчеты и средние значения и позволить им создаваться в новых столбцах за период даты.
Мои данные выглядят примерно так:
df = pd.DataFrame({
"USER_ID": ["AA1", "AB1", "AA3", "CD3", "AB4", "AA1", "AA1", "AA3", "AB4", "AB4"],
"ACTIVITY_CATEGORY": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
"DATE": ['2018-09-19', '2018-09-13', '2018-09-06', '2018-09-18', '2018-09-15', '2018-09-19', '2018-09-16', '2018-09-06', '2018-09-04', '2018-09-04']})
Итак, я обычно делаю это следующим образом:
df.groupby(['USER_ID',pd.Grouper(key='DATE', freq='W')])['ACTIVITY_CATEGORY'].count()
Но то, что я хочу сейчас, это иметь возможность получить его на определенную неделю. По сути, можно получить что-то вроде:
Я прочитал документацию о различных способах группировки в Grouper и возможных смещениях. До сих пор не могу найти что-то подобное.
Существует довольно громоздкий способ сделать это с помощью цикла for и с помощью timedelta и вычитания 7 дней из последнего дня, но он крайне неэффективен для большого набора данных. Ищете более питонический способ.
Привет, Дэниел, ну да, в этой конкретной подгруппе пользователей нет действий, происходящих на неделе 1, но в целом есть пользователи, у которых есть действия и на неделе 1, поэтому мне нужно иметь столбец для этого.
Итак, что будет неделя 1, неделя 2, неделя 3, неделя 4?






это похоже на то, что вы пытаетесь достичь
df['DATE'] = 'WEEK ' + pd.to_numeric(pd.to_datetime(df['DATE']).dt.day/7).apply(math.ceil).apply(str)
df.pivot_table(index=['USER_ID'],columns=['DATE'],aggfunc='count').fillna(0)
Вне:
ACTIVITY_CATEGORY
DATE WEEK 1 WEEK 2 WEEK 3
USER_ID
AA1 0.0 0.0 3.0
AA3 2.0 0.0 0.0
AB1 0.0 1.0 0.0
AB4 2.0 0.0 1.0
CD3 0.0 0.0 1.0
Сделано очень красноречиво, но проблема та же, что и у anky_91. Я не обобщаю, чтобы перейти к неделе 5, 6, 7 и т. д. Он группирует действия в рамках корзины с недели 1 по неделю 4, когда я включаю данные за предыдущие месяцы.
IIUC, вы можете попробовать это:
df_new=df.groupby(['USER_ID',pd.Grouper(key='DATE', freq='W')])['ACTIVITY_CATEGORY']\
.count().reset_index()
df_new['week_num']=(df_new.DATE.dt.day//7)+1
print(df_new.pivot_table(index='USER_ID',columns=['week_num']).fillna(0))
ACTIVITY_CATEGORY
week_num 2 3 4
USER_ID
AA1 0.0 1.0 2.0
AA3 2.0 0.0 0.0
AB1 0.0 1.0 0.0
AB4 2.0 1.0 0.0
CD3 0.0 0.0 1.0
Если присутствует неделя 1, она должна автоматически заполниться.
Это работает именно так, как показывает мой ожидаемый результат, однако проблема с этим подходом заключается в том, что он не работает более 1 месяца. т. е. неделя 5, неделя 6, неделя 7... неделя N. Из-за f_new.DATE.dt.day//7 он объединяет данные за предыдущие месяцы в один и тот же набор от недели 1 до недели 4. Я должен был быть более конкретным в своем заявлении о проблеме.
@Ash, значит, ты хочешь, чтобы вывод основывался на номерах недель? Это означает, что независимо от недели года, под которую подпадает дата, вывод должен иметь это?
Да, напр. в этом примере, если бы у меня были данные за 2018–08 годы, они должны быть на неделе 5–8, а если бы у меня были данные за 2018–07 годы, они должны быть на неделе 9–13 и т. д.
Что такое неделя1, неделя2, неделя3...? Если я не ошибаюсь, у вашего ввода df всего 3 разные недели.