Когортный анализ с pandas

Есть таблица с данными вида

user_id, month, year, num1, num2, type_id, type_name

12345, 04, 2019, 0, 1, 111, data1
13245, 04, 2019, 0, 1, 111, data1
14235, 05, 2019, 1, 2, 112, data2
15423, 03, 2019, 0, 1, 112, data2

Нужно провести когортный анализ, чтобы результат получился таким:

month, year, num1, type_name, total_users_on_num1

4, 2019, 0, data1, 234
4, 2019, 1, data1, 365
...
4, 2019, 0, data2, 835
4, 2019, 1, data2, 927
...

Выгрузка должна быть по type_name с количеством пользователей на каждом num1. Когорта здесь – month, при котором num1 = 1.

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

df.groupby('type_name').count() дает counts, но превращает остальные столбцы в эти же counts. Кажется, что нужно сгруппировать по type_name – но дальше неясно, нужно ли группировать по month, потому что если бы здесь была множественная вложенная группировка, то получилась бы сводная таблица, а в конечной таблице на каждой строке есть данные (показатели month и year не 1 раз указаны, а для каждой строки).


Ответы (2 шт):

Автор решения: Ekaterina Frolova

Тут нужно использовать "оконный" запрос - не уверена, как это будет через pandas, но на чистом sql будет примерно следующее:

select t.month, t.year, t.num1, t.type_name, count(t.user_id) over (partition by t.type_name) as total_users_for_num1 from table t order by t.num1; 
→ Ссылка
Автор решения: merletta

Попробуйте так (где df - переменная, указывающая на ваш датафрейм):

df.groupby(["month", "year", "num1", "type_name"]). nunique()[['user_id']].reset_index().rename(columns={'user_id': 'total_users_on_num1'})

reset_index тут нужен для разворачивания обратно в табличку сгруппированных данных с составным индексом; nunique будет правильней использовать вместо count, потому что скорее всего пользователи могут повторяться; rename для красоты.

→ Ссылка