# функция для создания пользовательских профилей def get_profiles(sessions, orders, events, ad_costs, event_names=[]): # находим параметры первых посещений profiles = ( sessions.sort_values(by=['user_id', 'session_start']) .groupby('user_id') .agg( { 'session_start': 'first', 'channel': 'first', 'device': 'first', 'region': 'first', } ) .rename(columns={'session_start': 'first_ts'}) .reset_index() ) # для когортного анализа определяем дату первого посещения # и первый день месяца, в который это посещение произошло profiles['dt'] = profiles['first_ts'].dt.date profiles['month'] = profiles['first_ts'].astype('datetime64[M]') # добавляем признак платящих пользователей profiles['payer'] = profiles['user_id'].isin(orders['user_id'].unique()) # добавляем флаги для всех событий из event_names for event in event_names: if event in events['event_name'].unique(): profiles[event] = profiles['user_id'].isin( events.query('event_name == @event')['user_id'].unique() ) # считаем количество уникальных пользователей # с одинаковыми источником и датой привлечения new_users = ( profiles.groupby(['dt', 'channel']) .agg({'user_id': 'nunique'}) .rename(columns={'user_id': 'unique_users'}) .reset_index() ) # объединяем траты на рекламу и число привлечённых пользователей ad_costs = ad_costs.merge(new_users, on=['dt', 'channel'], how='left') # делим рекламные расходы на число привлечённых пользователей ad_costs['acquisition_cost'] = ad_costs['costs'] / ad_costs['unique_users'] # добавляем стоимость привлечения в профили profiles = profiles.merge( ad_costs[['dt', 'channel', 'acquisition_cost']], on=['dt', 'channel'], how='left', ) # стоимость привлечения органических пользователей равна нулю profiles['acquisition_cost'] = profiles['acquisition_cost'].fillna(0) return profiles