Условие
Дан массив из 5385 транзакций. Для прошедших платежей (Financial Status = "Charged") посчитать на каждый день:
- DPU (Daily Paying Users) — количество уникальных платящих пользователей за день.
- NPU (New Paying Users) — количество впервые заплативших пользователей за день.
Решение
Pandas
import pandas as pd
df = pd.read_excel('test_excel.xlsx')
df = df[df['Financial Status'] == 'Charged'].copy()
df['date'] = pd.to_datetime(df['Date']).dt.date
# DPU
dpu = df.groupby('date')['user_id'].nunique().rename('DPU')
# NPU: дата первого платежа каждого пользователя
first_pay = df.groupby('user_id')['date'].min().reset_index(name='first_date')
npu = first_pay.groupby('first_date').size().rename('NPU')
result = pd.concat([dpu, npu], axis=1).fillna(0).astype(int).reset_index()
result.to_excel('result.xlsx', index=False)Только Excel-формулы
Если ограничено Excel:
DPU= на отдельном листе свод:=COUNTIFS(date_col, A2, fin_status_col, "Charged")с уникальными — лучше Power Pivot/UNIQUE+COUNTIFS.NPU: вспомогательная колонкаis_first—=IF(COUNTIFS(user_col, B2, date_col, "<"&A2, fin_status_col, "Charged")=0, 1, 0). ЗатемSUMIFS(is_first, date_col, ...).
Подводные камни
- Возвраты: если транзакция отменена — её счёт DPU считаться не должен. Фильтр
Chargedэто решает. - Один пользователь — несколько платежей в день: DPU считает уникальных, простой COUNT неверен.
- NPU должен быть < DPU; сумма NPU за весь период = число уникальных пользователей.
- Дата может быть с временем — обязательно
.dt.dateилиDATE(). - На бесконечно длинной истории NPU в первый день может «съесть» всех — нужен корректный horizon.
Эталонный ответ
DPU = nunique(user) по дням; NPU = группировка по дате первого платежа каждого user_id.