调整留存和ltv

This commit is contained in:
wuaho 2021-11-04 16:36:15 +08:00
parent 9abbfb637d
commit b37987e845
8 changed files with 127 additions and 8 deletions

View File

@ -1,8 +1,9 @@
import json
from aioredis import Redis
from fastapi import APIRouter, Depends, Request
from fastapi import APIRouter, Depends, Request, File
from motor.motor_asyncio import AsyncIOMotorDatabase
import pandas as pd
import crud, schemas
@ -31,7 +32,7 @@ async def read_data_attr(
data = json.loads(data)
res = []
data_attr = await crud.data_attr.find_many(db, {'game':game, 'cat':cat})
data_attr = await crud.data_attr.find_many(db, {'game': game, 'cat': cat})
data_attr = {item['name']: item for item in data_attr}
for k, v in data.items():
@ -61,3 +62,70 @@ async def edit_data_attr(
return schemas.Msg(code=0, msg='ok', data=data_in)
#
# @router.post("/add_select_map")
# async def add_map(
# request: Request,
# game: str,
# data_in: schemas.SelectMap,
# db: AsyncIOMotorDatabase = Depends(get_database),
# current_user: schemas.UserDB = Depends(deps.get_current_user)
# ) -> schemas.Msg:
# """添加属性值选择映射"""
#
# """
# {
# game:aaa,
# attr_name:bbb,
# map_:{
# '区服aa':'1',
# '区服vvv':'5',
# }
#
# }
# """
# await crud.select_map.save(db, data_in)
# return schemas.Msg(code=0, msg='ok', data=data_in)
@router.post("/add_select_map")
async def add_select_map(
request: Request,
game: str,
file: bytes = File(...),
db: AsyncIOMotorDatabase = Depends(get_database),
current_user: schemas.UserDB = Depends(deps.get_current_user)
) -> schemas.Msg:
"""添加属性值选择映射"""
dfs = pd.read_excel(file, engine='openpyxl', sheet_name=None)
for attr_name, df in dfs.items():
map_ = df.to_dict('records')
data_in = schemas.SelectMap(game=game, attr_name=attr_name, map_=map_)
await crud.select_map.save(db, data_in)
return schemas.Msg(code=0, msg='ok', data=1)
@router.get("/select_list")
async def select_list(
request: Request,
game: str,
db: AsyncIOMotorDatabase = Depends(get_database),
current_user: schemas.UserDB = Depends(deps.get_current_user)
) -> schemas.Msg:
"""属性值选择映射列表"""
resp = await crud.select_map.get_list(db, game)
return schemas.Msg(code=0, msg='ok', data=resp)
@router.post("/select_attr")
async def select_attr(
request: Request,
game: str,
data_in: schemas.SelectAttr,
db: AsyncIOMotorDatabase = Depends(get_database),
current_user: schemas.UserDB = Depends(deps.get_current_user)
) -> schemas.Msg:
"""属性值选择映射"""
resp = await crud.select_map.get_select(db, data_in, game)
return schemas.Msg(code=0, msg='ok', data=resp)

View File

@ -329,7 +329,7 @@ async def retention_model(request: Request,
n = (pd.Timestamp.now().date() - date).days
if i > n:
continue
max_retention_n = i if i > max_retention_n else max_retention_n
# max_retention_n = i if i > max_retention_n else max_retention_n
avg[i] = avg.setdefault(i, 0) + v[f'cnt{i}']
avgo[i] = avgo.setdefault(i, 0) + v[f'on{i}']
tmp['p'].append(v[f'p{i}'])
@ -343,7 +343,13 @@ async def retention_model(request: Request,
tmp['p_outflow'] = (pd.Series(avgo) * 100 / tmp['d0']).round(2).tolist()
tmp['n_outflow'] = pd.Series(avgo).values.tolist()
title = ['日期', '用户数', '次留', *[f'{i}' for i in retention_n[1:] if i <= max_retention_n]]
title = ['日期', '用户数', '次留', *[f'{i}' for i in retention_n[1:]]]
# 未到达的日期需要补齐-
retention_length = len(retention_n)
for _, items in summary_values.items():
for key in ['p', 'n', 'p_outflow', 'n_outflow']:
items[key].extend(['-'] * (retention_length - len(items[key])))
resp = {
'summary_values': summary_values,

View File

@ -12,4 +12,5 @@ from .crud_event_mana import event_mana
from .crud_api_list import api_list
from .crud_role import role
from .crud_check_data import check_data
from .user_label import user_label
from .user_label import user_label
from .select_map import select_map

30
crud/select_map.py Normal file
View File

@ -0,0 +1,30 @@
from motor.motor_asyncio import AsyncIOMotorDatabase
import schemas
from crud.base import CRUDBase
__all__ = 'select_map',
class CRUDSelectMap(CRUDBase):
async def save(self, db: AsyncIOMotorDatabase, data_in: schemas.SelectMap):
where = {'attr_name': data_in.attr_name, 'game': data_in.game}
return await self.update_one(db, where, {'$set': data_in.dict(skip_defaults=True)}, upsert=True)
# async def read(self, db: AsyncIOMotorDatabase, data_in: schemas.SelectMap):
# where = data_in.dict(skip_defaults=True)
# res = await self.find_many(db, where)
# return res
#
async def get_list(self, db: AsyncIOMotorDatabase, game: str):
where = {'game': game}
res = await self.find_many(db, where, {'_id': 0})
return res
async def get_select(self, db: AsyncIOMotorDatabase, data_in: schemas.SelectAttr, game: str):
where = {'game': game, **data_in.dict()}
res = await self.find_one(db, where, {'_id': 0})
return res
select_map = CRUDSelectMap('select_map')

View File

@ -771,7 +771,7 @@ ORDER BY values desc"""
days = (arrow.get(self.end_date).date() - arrow.get(self.start_date).date()).days
keep = []
cnt = []
retention_n = [*[k for k in range(1, 31)], 45, 60, 90, 120, 180, 240, 300, 360]
retention_n = [*[k for k in range(1, 61)], 90, 120, 180, 240, 300, 360]
"""
cnt0-cnt1 as on1,

View File

@ -132,7 +132,7 @@ class XAnalysis:
sumpay = []
sum_money = []
# for i in range(1, days + 2):
ltv_n = [*[k for k in range(1, 31)], 45, 60, 90, 120, 180, 240, 300, 360]
ltv_n = [*[k for k in range(1, 61)], 90, 120, 180, 240, 300, 360]
for i in ltv_n:
# select_ltv.append(func.round(sa.Column(f'sumpay_{i}') / sa.Column('cnt1'), 2).label(f'LTV{i}'))
select_ltv.append(

View File

@ -16,4 +16,5 @@ from .xquery import *
from .api_list import *
from .role import *
from .check_data import *
from .userlabel import *
from .userlabel import *
from .select_map import *

13
schemas/select_map.py Normal file
View File

@ -0,0 +1,13 @@
from typing import Any, List, Union, Dict
from pydantic import BaseModel, Field
class SelectMap(BaseModel):
game: str
attr_name: str
map_: List[Dict]
class SelectAttr(BaseModel):
attr_name: str