Pandas groupby date - определенные периоды дат

Я хочу иметь возможность группировать свои данные по пользователю, а затем по определенным периодам дат, чтобы получить подсчеты и средние значения и позволить им создаваться в новых столбцах за период даты.

Мои данные выглядят примерно так:

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()

Но то, что я хочу сейчас, это иметь возможность получить его на определенную неделю. По сути, можно получить что-то вроде:

Pandas groupby date - определенные периоды дат

Я прочитал документацию о различных способах группировки в Grouper и возможных смещениях. До сих пор не могу найти что-то подобное.

Существует довольно громоздкий способ сделать это с помощью цикла for и с помощью timedelta и вычитания 7 дней из последнего дня, но он крайне неэффективен для большого набора данных. Ищете более питонический способ.

Что такое неделя1, неделя2, неделя3...? Если я не ошибаюсь, у вашего ввода df всего 3 разные недели.

Dani Mesejo 02.02.2019 15:32

Привет, Дэниел, ну да, в этой конкретной подгруппе пользователей нет действий, происходящих на неделе 1, но в целом есть пользователи, у которых есть действия и на неделе 1, поэтому мне нужно иметь столбец для этого.

DaytaSigntist 02.02.2019 15:36

Итак, что будет неделя 1, неделя 2, неделя 3, неделя 4?

Dani Mesejo 02.02.2019 15:46
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
230
2

Ответы 2

это похоже на то, что вы пытаетесь достичь

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, когда я включаю данные за предыдущие месяцы.

DaytaSigntist 02.02.2019 23:29

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. Я должен был быть более конкретным в своем заявлении о проблеме.

DaytaSigntist 02.02.2019 23:26

@Ash, значит, ты хочешь, чтобы вывод основывался на номерах недель? Это означает, что независимо от недели года, под которую подпадает дата, вывод должен иметь это?

anky 03.02.2019 03:23

Да, напр. в этом примере, если бы у меня были данные за 2018–08 годы, они должны быть на неделе 5–8, а если бы у меня были данные за 2018–07 годы, они должны быть на неделе 9–13 и т. д.

DaytaSigntist 03.02.2019 14:55

Другие вопросы по теме