Посчитать уникальные текстовые значения в столбце нарастающим итогом (по месяцам)
Есть таблица:
-- для теста
df = pd.DataFrame(({'date': ['2021-10-02', '2021-10-02', '2021-11-02', '2021-12-02', '2022-01-02'],
'user_id': ['user_1', 'user_2', 'user_9', 'user_5', 'user_1'],
'year': [2021, 2021, 2021, 2021, 2022],
'month': [10, 10, 11, 12, 1],
'week': [39, 39, 42, 48, 1]}))
df['date'] = pd.to_datetime(df['date'])
date user_id year month week
0 2021-10-02 user_1 2021 10 39
1 2021-10-02 user_2 2021 10 39
2 2021-11-02 user_9 2021 11 42
3 2021-12-02 user_5 2021 12 48
4 2022-01-02 user_1 2022 01 01
Мне нужно посчитать уникальное количество юзеров нарастающим итогом по месяцам (неделям):
year month cum_number_users
2021 10 2
2021 11 3
2021 12 4
2022 01 4
Я пробовала код со всевозможными вариациями:
table = df.groupby(['year', 'month'], as_index=False).agg({'user_id': 'nunique'})
Но так выводится уникальное количество юзеров по каждому месяцу. Метод cumsum() работает только с числами.
Можно также вручную посчитать нарастающий итог через query:
df.query("10 <= month <= 11").agg({'user_id': 'nunique'}) # за октябрь и ноябрь
или
df.query("10 <= month <= 12").agg({'user_id': 'nunique'}) # за октябрь, ноябрь и декабрь
Но мне нужно не вручную. Вот никак не соображу :(
Ответы (1 шт):
Когда вы применяете группировку, аггрегирующая функция применяется только к группе.
Я бы рекомендовал сделать так:
- сначала проверяете, является ли
user_idдубликатом,если да, помечаете его и инвертируете отметку - делаете свою группировку с суммированием положительных отметок (не дубликаты) в колонке
user_id - считаете кумулятивную сумму по колонке
user_id
df["user_id"] = (~df["user_id"].duplicated())
table = df.groupby(['year', 'month'], as_index=False)["user_id"].sum()
table["user_id"] = table["user_id"].cumsum()
table:
year month user_id
0 2021 10 2
1 2021 11 3
2 2021 12 4
3 2022 1 4