- # функция для расчёта конверсии
- def get_conversion(
- profiles,
- purchases,
- observation_date,
- horizon_days,
- dimensions=[],
- ignore_horizon=False,
- ):
- # исключаем пользователей, не «доживших» до горизонта анализа
- last_suitable_acquisition_date = observation_date
- if not ignore_horizon:
- last_suitable_acquisition_date = observation_date - timedelta(
- days=horizon_days - 1
- )
- result_raw = profiles.query('dt <= @last_suitable_acquisition_date')
- # определяем дату и время первой покупки для каждого пользователя
- first_purchases = (
- purchases.sort_values(by=['user_id', 'event_dt'])
- .groupby('user_id')
- .agg({'event_dt': 'first'})
- .reset_index()
- )
- # добавляем данные о покупках в профили
- result_raw = result_raw.merge(
- first_purchases[['user_id', 'event_dt']], on='user_id', how='left'
- )
- # рассчитываем лайфтайм для каждой покупки
- result_raw['lifetime'] = (
- result_raw['event_dt'] - result_raw['first_ts']
- ).dt.days
- # группируем по cohort, если в dimensions ничего нет
- if len(dimensions) == 0:
- result_raw['cohort'] = 'All users'
- dimensions = dimensions + ['cohort']
- # функция для группировки таблицы по желаемым признакам
- def group_by_dimensions(df, dims, horizon_days):
- result = df.pivot_table(
- index=dims, columns='lifetime', values='user_id', aggfunc='nunique'
- )
- result = result.fillna(0).cumsum(axis = 1)
- cohort_sizes = (
- df.groupby(dims)
- .agg({'user_id': 'nunique'})
- .rename(columns={'user_id': 'cohort_size'})
- )
- result = cohort_sizes.merge(result, on=dims, how='left').fillna(0)
- # делим каждую «ячейку» в строке на размер когорты
- # и получаем conversion rate
- result = result.div(result['cohort_size'], axis=0)
- result = result[['cohort_size'] + list(range(horizon_days))]
- result['cohort_size'] = cohort_sizes
- return result
- # получаем таблицу конверсии
- result_grouped = group_by_dimensions(result_raw, dimensions, horizon_days)
- # для таблицы динамики конверсии убираем 'cohort' из dimensions
- if 'cohort' in dimensions:
- dimensions = []
- # получаем таблицу динамики конверсии
- result_in_time = group_by_dimensions(
- result_raw, dimensions + ['dt'], horizon_days
- )
- # возвращаем обе таблицы и сырые данные
- return result_raw, result_grouped, result_in_time