调整留存和ltv
This commit is contained in:
parent
9abbfb637d
commit
b37987e845
@ -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)
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
30
crud/select_map.py
Normal 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')
|
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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
13
schemas/select_map.py
Normal 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
|
Loading…
Reference in New Issue
Block a user