调整留存和ltv
This commit is contained in:
parent
9abbfb637d
commit
b37987e845
@ -1,8 +1,9 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
from aioredis import Redis
|
from aioredis import Redis
|
||||||
from fastapi import APIRouter, Depends, Request
|
from fastapi import APIRouter, Depends, Request, File
|
||||||
from motor.motor_asyncio import AsyncIOMotorDatabase
|
from motor.motor_asyncio import AsyncIOMotorDatabase
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
import crud, schemas
|
import crud, schemas
|
||||||
|
|
||||||
@ -61,3 +62,70 @@ async def edit_data_attr(
|
|||||||
return schemas.Msg(code=0, msg='ok', data=data_in)
|
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
|
n = (pd.Timestamp.now().date() - date).days
|
||||||
if i > n:
|
if i > n:
|
||||||
continue
|
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}']
|
avg[i] = avg.setdefault(i, 0) + v[f'cnt{i}']
|
||||||
avgo[i] = avgo.setdefault(i, 0) + v[f'on{i}']
|
avgo[i] = avgo.setdefault(i, 0) + v[f'on{i}']
|
||||||
tmp['p'].append(v[f'p{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['p_outflow'] = (pd.Series(avgo) * 100 / tmp['d0']).round(2).tolist()
|
||||||
tmp['n_outflow'] = pd.Series(avgo).values.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 = {
|
resp = {
|
||||||
'summary_values': summary_values,
|
'summary_values': summary_values,
|
||||||
|
@ -13,3 +13,4 @@ from .crud_api_list import api_list
|
|||||||
from .crud_role import role
|
from .crud_role import role
|
||||||
from .crud_check_data import check_data
|
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
|
days = (arrow.get(self.end_date).date() - arrow.get(self.start_date).date()).days
|
||||||
keep = []
|
keep = []
|
||||||
cnt = []
|
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,
|
cnt0-cnt1 as on1,
|
||||||
|
@ -132,7 +132,7 @@ class XAnalysis:
|
|||||||
sumpay = []
|
sumpay = []
|
||||||
sum_money = []
|
sum_money = []
|
||||||
# for i in range(1, days + 2):
|
# 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:
|
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(func.round(sa.Column(f'sumpay_{i}') / sa.Column('cnt1'), 2).label(f'LTV{i}'))
|
||||||
select_ltv.append(
|
select_ltv.append(
|
||||||
|
@ -17,3 +17,4 @@ from .api_list import *
|
|||||||
from .role import *
|
from .role import *
|
||||||
from .check_data 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