diff --git a/api/api_v1/endpoints/query.py b/api/api_v1/endpoints/query.py index e8590ab..f082a5f 100644 --- a/api/api_v1/endpoints/query.py +++ b/api/api_v1/endpoints/query.py @@ -207,9 +207,49 @@ async def funnel_model( res = analysis.funnel_model_sql() sql = res['sql'] date_range = res['date_range'] + cond_level = res['cond_level'] + groupby = res['groupby'] df = await ckdb.query_dataframe(sql) + # df.set_index('date',inplace=True) + data = {'level': cond_level} + if groupby: + # 补齐数据 + concat_data = [] + idx = set(df.set_index(groupby).index) + all_idx = {(j, i) for i in range(1, len(cond_level) + 1) for j in idx} + for i in all_idx - set(df.set_index(list((*groupby, 'level'))).index): + concat_data.append((*i, 0)) + df = pd.concat([df, pd.DataFrame(concat_data, columns=df.columns)]) + # df.sort_values(list((*groupby, 'level')), inplace=True, ascending=False) + + for key, tmp_df in df.groupby(groupby): + tmp = data.setdefault(key, {}) + tmp_df.set_index('level', inplace=True) + tmp_df.sort_index(inplace=True) + for i in tmp_df.index: + tmp_df.loc[i, 'values'] = tmp_df.loc[i:]['values'].sum() + + tmp['n'] = tmp_df['values'].to_list() + tmp['p1'] = [100] + tmp['p2'] = [] + for i, v in tmp_df.loc[2:, 'values'].items(): + tmp['p1'].append(round(v*100 / tmp_df.loc[1, 'values'], 2)) + # tmp['p2'].append(round(v*100 / tmp_df.loc[i - 1, 'values'], 2)) + + else: + tmp = data.setdefault('全部', {}) + df.set_index('level', inplace=True) + df.sort_index(inplace=True) + for i in df.index: + df.loc[i, 'values'] = df.loc[i:]['values'].sum() + + tmp['n'] = df['values'].to_list() + tmp['p1'] = [100] + tmp['p2'] = [] + for i, v in df.loc[2:, 'values'].items(): + tmp['p1'].append(round(v*100 / df.loc[1, 'values'], 2)) + # tmp['p2'].append(round(v*100 / df.loc[i - 1, 'values'], 2)) - data = {} return schemas.Msg(code=0, msg='ok', data=data) diff --git a/models/behavior_analysis.py b/models/behavior_analysis.py index 6c2d2ef..9754ffb 100644 --- a/models/behavior_analysis.py +++ b/models/behavior_analysis.py @@ -245,11 +245,13 @@ ORDER BY level sub_group = [*self.groupby, e_account_id_col] conds = [] + cond_level = [] for item in self.events: event_filter, _ = self.handler_filts(*item['filts'], g_f=False) conds.append( and_(event_name_col == item['eventName'], *event_filter) ) + cond_level.append(item['eventName']) # todo 替换 _windows_gap_ subq = sa.select(*[sa.Column(i.key) for i in self.groupby], func.windowFunnel_windows_gap__(event_time_col, *conds).label('level')).select_from( @@ -270,9 +272,10 @@ ORDER BY level .group_by(*[sa.Column(i.key) for i in self.groupby], sa.Column('level')) \ .order_by(*[sa.Column(i.key) for i in self.groupby], sa.Column('level')) sql = str(qry.compile(compile_kwargs={"literal_binds": True})) - sql = sql.replace('_windows_gap_', f'({windows_gap})') + sql = sql.replace('_windows_gap_', f"({windows_gap},'strict_increase')") print(sql) return {'sql': sql, 'groupby': [i.key for i in self.groupby], 'date_range': self.date_range, + 'cond_level': cond_level }