Untitled

From Whipped Pig, 9 Months ago, written in Plain Text, viewed 96 times.
URL http://codebin.org/view/79577185 Embed
Download Paste or View Raw
  1. import pandas as pd
  2. from datetime import datetime, timedelta
  3. import seaborn as sns
  4. from matplotlib import pyplot as plt
  5.  
  6.  
  7. def get_ltv(
  8.     profiles,
  9.     purchases,
  10.     observation_date,
  11.     horizon_days,
  12.     dimensions=[],
  13.     ignore_horizon=False,
  14. ):
  15.  
  16.     # исключаем пользователей, не «доживших» до горизонта анализа
  17.     last_suitable_acquisition_date = observation_date
  18.     if not ignore_horizon:
  19.         last_suitable_acquisition_date = observation_date - timedelta(
  20.             days=horizon_days - 1
  21.         )
  22.     result_raw = profiles.query('dt <= @last_suitable_acquisition_date')
  23.  
  24.     # добавляем данные о выручке в профили
  25.     result_raw = result_raw.merge(
  26.         purchases[['user_id', 'event_dt', 'revenue']],
  27.         on='user_id',
  28.         how='left',
  29.     )
  30.  
  31.     # вычисляем лайфтайм для каждой покупки
  32.     result_raw['lifetime'] = (
  33.         result_raw['event_dt'] - result_raw['first_ts']
  34.     ).dt.days
  35.  
  36.     # группируем по cohort, если в dimensions ничего нет
  37.     if len(dimensions) == 0:
  38.         result_raw['cohort'] = 'All users'
  39.         dimensions = dimensions + ['cohort']
  40.  
  41.     def group_by_dimensions(df, dims, horizon_days):
  42.         # строим «треугольную» таблицу выручки
  43.         result = df.pivot_table(
  44.             index=dims,
  45.             columns='lifetime',
  46.             values='revenue',
  47.             aggfunc='sum',
  48.         )
  49.         # считаем сумму выручки с накоплением
  50.         result = result.fillna(0).cumsum(axis=1)
  51.         # вычисляем размеры когорт
  52.         cohort_sizes = (
  53.             df.groupby(dims)
  54.             .agg({'user_id': 'nunique'})
  55.             .rename(columns={'user_id': 'cohort_size'})
  56.         )
  57.         # объединяем размеры когорт и таблицу выручки
  58.         result = cohort_sizes.merge(result, on=dims, how='left').fillna(0)
  59.         # считаем LTV:
  60.         # делим каждую «ячейку» в строке на размер когорты
  61.         result = result.div(result['cohort_size'], axis=0)
  62.         # исключаем все лайфтаймы, превышающие горизонт анализа
  63.         result = result[['cohort_size'] + list(range(horizon_days))]
  64.         # восстанавливаем размеры когорт
  65.         result['cohort_size'] = cohort_sizes
  66.         return result
  67.  
  68.     # получаем таблицу LTV
  69.     result_grouped = group_by_dimensions(result_raw, dimensions, horizon_days)
  70.  
  71.     # для таблицы динамики конверсии убираем 'cohort' из dimensions
  72.     if 'cohort' in dimensions:
  73.         dimensions = []
  74.     # получаем таблицу динамики LTV
  75.     result_in_time = group_by_dimensions(
  76.         result_raw, dimensions + ['dt'], horizon_days
  77.     )
  78.  
  79.     # возвращаем обе таблицы LTV и сырые данные
  80.     return result_raw, result_grouped, result_in_time
  81.  
  82.  
  83. users = pd.read_csv('ch02_problems02_users.csv')  # профили
  84. purchases = pd.read_csv('ch02_problems02_orders.csv')  # данные о покупках
  85.  
  86. # преобразование данных о времени
  87. users['dt'] = pd.to_datetime(users['dt']).dt.date
  88. users['first_ts'] = pd.to_datetime(users['first_ts'])
  89. purchases['event_dt'] = pd.to_datetime(purchases['event_dt'])
  90.  
  91. observation_date = users['dt'].max()  # момент анализа
  92. analysis_horizon = 7  # горизонт анализа
  93.  
  94. users = users.query('channel == "Organic"')
  95. ltv_raw, ltv, ltv_history = get_ltv(
  96.     users, purchases, observation_date, analysis_horizon
  97. )
  98.  
  99. ltv_history[5].sort_values().head(1)

Reply to "Untitled"

Here you can reply to the paste above