Python/普康健康机构绩效/main.py

577 lines
18 KiB
Python

from decimal import Decimal, ROUND_HALF_UP
import pandas
from utils.pandas_extension import save_as_workbook
dataset = {}
# 机构绩效基础数据
sheets = pandas.ExcelFile("基础数据.xlsx")
for sheet_name in sheets.sheet_names:
dataset[sheet_name] = pandas.read_excel(sheets, sheet_name=sheet_name, dtype=str)
# 根据年度达成率映射为年终奖
def mapped_as_regional_year_end_bonus(x: Decimal) -> str:
# noinspection PyUnreachableCode
match x:
case x if x < 70:
z = "0薪"
case x if 70 <= x < 80:
z = "4薪"
case x if 80 <= x < 90:
z = "5薪"
case x if 90 <= x < 100:
z = "6薪"
case x if 100 <= x < 110:
z = "7薪"
case x if 110 <= x < 120:
z = "8薪"
case x if 120 <= x < 130:
z = "9薪"
case x if 130 <= x < 140:
z = "10薪"
case x if 140 <= x < 150:
z = "11薪"
case x if x >= 150:
z = "12薪"
case _:
z = "年度达成率未匹配年终奖"
return z
# 大区年终薪酬
# 就大区机构周报,筛选大区/机构名称包含大区的行、年度消费目标(万)/累计消费规模(万)/年度达成率,根据年度达成率匹配年终奖基准额度
regional_year_end_bonus = (
dataset["大区机构达成率1"]
.loc[
dataset["大区机构达成率1"]["大区/机构名称"].str.contains("大区"),
["大区/机构名称", "年度消费目标(万)", "累计消费规模(万)", "年度达成率"],
]
.assign(
年度达成率=lambda dataframe: dataframe["年度达成率"].apply(
lambda cell: (Decimal(cell) * 100).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
),
)
)
.assign(
年终奖=lambda dataframe: dataframe["年度达成率"].apply(
lambda cell: mapped_as_regional_year_end_bonus(cell)
)
)
.sort_values(by="年度达成率", ascending=False)
.reset_index(drop=True)
)
def mapped_as_institutional_year_end_bonus(x: pandas.Series) -> str | None:
if x["年度达成率"] < 70:
if (
x["大区/机构名称"]
in "安徽、河南、浙江、上海、云南、湖北、广东、广西、河北、江苏、江西、甘肃、黑吉、辽宁、山西、新疆、四川"
):
z = "0薪"
else:
z = None
elif 70 <= x["年度达成率"] < 80:
if (
x["大区/机构名称"]
in "安徽、河南、浙江、上海、云南、湖北、广东、广西、河北、江苏、江西、甘肃"
):
z = "0薪"
elif x["大区/机构名称"] in "黑吉、辽宁、山西、新疆、四川":
z = "2薪"
else:
z = None
elif 80 <= x["年度达成率"] < 90:
if x["大区/机构名称"] in "安徽、河南、浙江、上海、云南、湖北、广东、广西":
z = "0薪"
elif x["大区/机构名称"] in "河北、江苏、江西、甘肃":
z = "2薪"
elif x["大区/机构名称"] in "黑吉、辽宁、山西、新疆、四川":
z = "3薪"
else:
z = None
elif 90 <= x["年度达成率"] < 100:
if x["大区/机构名称"] in "安徽、河南、浙江、上海、云南、湖北、广东、广西":
z = "2薪"
elif x["大区/机构名称"] in "河北、江苏、江西、甘肃":
z = "3薪"
elif x["大区/机构名称"] in "黑吉、辽宁、山西、新疆、四川":
z = "4薪"
else:
z = None
elif 100 <= x["年度达成率"] < 120:
if x["大区/机构名称"] in "安徽、河南、浙江、上海、云南、湖北、广东、广西":
z = "3薪"
elif x["大区/机构名称"] in "河北、江苏、江西、甘肃":
z = "4薪"
elif x["大区/机构名称"] in "黑吉、辽宁、山西、新疆、四川":
z = "5薪"
else:
z = None
elif 120 <= x["年度达成率"] < 140:
if x["大区/机构名称"] in "安徽、河南、浙江、上海、云南、湖北、广东、广西":
z = "4薪"
elif x["大区/机构名称"] in "河北、江苏、江西、甘肃":
z = "5薪"
elif x["大区/机构名称"] in "黑吉、辽宁、山西、新疆、四川":
z = "6薪"
else:
z = None
elif 140 <= x["年度达成率"] < 160:
if x["大区/机构名称"] in "安徽、河南、浙江、上海、云南、湖北、广东、广西":
z = "5薪"
elif x["大区/机构名称"] in "河北、江苏、江西、甘肃":
z = "6薪"
elif x["大区/机构名称"] in "黑吉、辽宁、山西、新疆、四川":
z = "7薪"
else:
z = None
elif 160 <= x["年度达成率"] < 180:
if x["大区/机构名称"] in "安徽、河南、浙江、上海、云南、湖北、广东、广西":
z = "6薪"
elif x["大区/机构名称"] in "河北、江苏、江西、甘肃":
z = "7薪"
elif x["大区/机构名称"] in "黑吉、辽宁、山西、新疆、四川":
z = "8薪"
else:
z = None
elif 180 <= x["年度达成率"] < 200:
if (
x["大区/机构名称"]
in "安徽、河南、浙江、上海、云南、湖北、广东、广西、河北、江苏、江西、甘肃"
):
z = "8薪"
elif x["大区/机构名称"] in "黑吉、辽宁、山西、新疆、四川":
z = "9薪"
else:
z = None
else:
if (
x["大区/机构名称"]
in "安徽、河南、浙江、上海、云南、湖北、广东、广西、河北、江苏、江西、甘肃、黑吉、辽宁、山西、新疆、四川"
):
z = "10薪"
else:
z = None
return z
# 机构年终薪酬
institutional_year_end_bonus = (
dataset["大区机构达成率1"]
.loc[
~dataset["大区机构达成率1"]["大区/机构名称"].str.contains("大区")
& ~dataset["大区机构达成率1"]["大区/机构名称"].isin(["宁夏(只宁煤)"]),
["大区/机构名称", "年度消费目标(万)", "累计消费规模(万)", "年度达成率"],
]
.assign(
年度达成率=lambda dataframe: dataframe["年度达成率"].apply(
lambda cell: (Decimal(cell) * 100).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
),
)
)
.assign(
年终奖=lambda dataframe: dataframe[["大区/机构名称", "年度达成率"]].apply(
lambda row: mapped_as_institutional_year_end_bonus(row), axis="columns"
)
)
.dropna(subset=["年终奖"])
.sort_values(by="年度达成率", ascending=False)
.reset_index(drop=True)
)
# 根据机构所在省份匹配为机构名称
def mapped_as_institution_name(x):
# noinspection PyUnreachableCode
match x:
case "北京市" | "天津市":
z = "京津"
case "河北省":
z = "河北"
case "山西省":
z = "山西"
case "内蒙古自治区":
z = "内蒙"
case "辽宁省":
z = "辽宁"
case "吉林省" | "黑龙江省":
z = "黑吉"
case "上海市":
z = "上海"
case "江苏省":
z = "江苏"
case "浙江省":
z = "浙江"
case "安徽省":
z = "安徽"
case "福建省":
z = "福建"
case "江西省":
z = "江西"
case "山东省":
z = "山东"
case "河南省":
z = "河南"
case "湖北省":
z = "湖北"
case "湖南省":
z = "湖南"
case "广东省" | "海南省":
z = "广东"
case "广西壮族自治区":
z = "广西"
case "重庆市" | "四川省" | "西藏自治区":
z = "四川"
case "贵州省":
z = "贵州"
case "云南省":
z = "云南"
case "新疆维吾尔自治区":
z = "新疆"
case "陕西省" | "青海省":
z = "陕西"
case "甘肃省":
z = "甘肃"
case "宁夏回族自治区":
z = "宁夏"
case "总部":
z = "总部"
case _:
z = ""
return z
# 根据发卡金额映射为奖励
def mapped_as_card_issuance_reward(x: Decimal) -> int:
# noinspection PyUnreachableCode
match x:
case x if 50 <= x < 100:
z = 500
case x if 100 <= x < 300:
z = 800
case x if 300 <= x < 500:
z = 1000
case x if 500 <= x < 1000:
z = 2000
case x if 1000 <= x < 3000:
z = 4000
case x if 3000 <= x < 5000:
z = 10000
case x if 5000 <= x < 10000:
z = 20000
case x if x >= 10000:
z = 30000
case _:
z = 0
return z
# 自主经营发卡奖励
card_issuance_reward = (
dataset["25年发卡"]
.loc[~dataset["25年发卡"]["投保公司"].isin(dataset["24年发卡"]["投保公司"])]
.merge(
dataset["保单机构分配"],
how="left",
on="保单编号",
suffixes=("", "_duplication"),
) # 若有发卡无消费则无保单机构分配方案
.fillna("0")
.assign(
发卡金额=lambda dataframe: dataframe["发卡金额"].apply(
lambda cell: (Decimal(cell) / 10000).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
)
) # 发卡金额单位为万元
)
.assign(
奖励金额=lambda dataframe: dataframe["发卡金额"].apply(
lambda cell: mapped_as_card_issuance_reward(cell)
)
) # 先计算奖励金额在根据机构分配比例拆分
.assign(总部="总部")
.assign(
# 整合机构
机构名称=lambda dataframe: dataframe.apply(
lambda x: [x["落地机构"], x["出单机构"], x["总部"]], axis="columns"
),
# 整合分配比例
分配比例=lambda dataframe: dataframe.apply(
lambda x: [
x["落地机构分配比例"],
x["出单机构分配比例"],
x["总部分配比例"],
],
axis="columns",
),
)
.explode(["机构名称", "分配比例"])
.assign(
分配后奖励金额=lambda dataframe: dataframe.apply(
lambda row: (
Decimal(row["奖励金额"]) * Decimal(row["分配比例"]) / 100
).quantize(Decimal("0.00"), rounding=ROUND_HALF_UP),
axis="columns",
),
)
.assign(
机构=lambda dataframe: dataframe["机构名称"].apply(
lambda cell: mapped_as_institution_name(cell)
)
)
.loc[lambda dataframe: dataframe["机构"] != "总部"] # 过滤总部
.sort_values(by="分配后奖励金额", ascending=False)
.reset_index(drop=True)
)[["保单编号", "投保公司", "保险总公司", "保险分公司", "发卡金额", "奖励金额", "机构", "分配比例", "分配后奖励金额"]]
# 根据转化率提升映射为奖励比例
def mapped_as_increase_reward_ratio(x: Decimal) -> Decimal:
# noinspection PyUnreachableCode
match x:
case x if 5 <= x < 10:
z = Decimal("0.1")
case x if 10 <= x < 15:
z = Decimal("0.2")
case x if 15 <= x < 20:
z = Decimal("0.3")
case x if 20 <= x < 30:
z = Decimal("0.4")
case x if x >= 30:
z = Decimal("0.5")
case _:
z = Decimal("0")
return z
# 重点存量业务消费提升奖励
increase_reward = (
dataset["投保公司"]
.loc[dataset["投保公司"]["项目名称"].isin(dataset["重点项目"]["项目名称"])]
.merge(
dataset["24年数据"], how="left", on="投保公司", suffixes=("", "_duplication")
)
.merge(
dataset["25年数据"], how="left", on="投保公司", suffixes=("", "_duplication")
)
.fillna("0")
.assign(
转化率25年=lambda dataframe: dataframe["25年转化率"].apply(
lambda row: (Decimal(row) * 100).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
)
),
转化率24年=lambda dataframe: dataframe["24年转化率"].apply(
lambda row: (Decimal(row) * 100).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
)
),
)
.assign(
转化率提升=lambda dataframe: dataframe.apply(
lambda row: (row["转化率25年"] - row["转化率24年"]).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
),
axis="columns",
)
)
.assign(
奖励比例=lambda dataframe: dataframe["转化率提升"].apply(
lambda cell: mapped_as_increase_reward_ratio(cell)
)
)
.assign(
消费金额提升=lambda dataframe: dataframe.apply(
lambda row: (
Decimal(row["25年消费金额"]) - Decimal(row["24年消费金额"])
).quantize(Decimal("0.00"), rounding=ROUND_HALF_UP),
axis="columns",
)
)
.assign(
奖励金额=lambda dataframe: dataframe.apply(
lambda row: (row["消费金额提升"] * row["奖励比例"] / 100).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
),
axis="columns",
)
)
.sort_values(by="奖励金额", ascending=False)
.reset_index(drop=True)
)[
[
"项目名称",
"投保公司",
"25年发卡金额",
"25年消费金额",
"转化率25年",
"24年发卡金额",
"24年消费金额",
"转化率24年",
"转化率提升",
"奖励比例",
"消费金额提升",
"奖励金额",
]
]
# 根据转化率映射为奖励比例
def mapped_as_new_reward_ratio(x: Decimal) -> Decimal:
# noinspection PyUnreachableCode
match x:
case x if 30 <= x < 40:
z = Decimal("0.3")
case x if 40 <= x < 50:
z = Decimal("0.4")
case x if 50 <= x < 60:
z = Decimal("0.5")
case x if 60 <= x < 70:
z = Decimal("0.6")
case x if 70 <= x < 80:
z = Decimal("0.7")
case x if 80 <= x < 90:
z = Decimal("0.8")
case x if x >= 90:
z = Decimal("1.0")
case _:
z = Decimal("0")
return z
# 新增业务消费奖励
new_reward = (
dataset["保单机构分配"]
.loc[
(dataset["保单机构分配"]["自力更生"] == "")
& ~dataset["保单机构分配"]["投保公司"].isin(dataset["24年发卡"]["投保公司"])
]
.merge(
dataset["25年发卡"],
how="left",
on="保单编号",
suffixes=("", "_duplication"),
)
.merge(
dataset["25年消费"], how="left", on="保单编号", suffixes=("", "_duplication")
)
.fillna("0")
.assign(
发卡金额=lambda dataframe: dataframe["发卡金额"].apply(
lambda cell: (Decimal(cell) / 10000).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
)
), # 发卡金额单位为万元
消费金额=lambda dataframe: dataframe["消费金额"].apply(
lambda cell: (Decimal(cell) / 10000).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
)
), # 消费金额单位为万元
)
.assign(
转化率=lambda dataframe: dataframe.apply(
lambda row: (
(row["消费金额"] / row["发卡金额"] * 100).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
)
if row["发卡金额"] != 0
else Decimal("0.00")
),
axis="columns",
)
)
.assign(
奖励比例=lambda dataframe: dataframe["转化率"].apply(
lambda cell: mapped_as_new_reward_ratio(cell)
)
)
.assign(
奖励金额=lambda dataframe: dataframe.apply(
lambda row: (row["消费金额"] * row["奖励比例"] / 100 * 10000).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
),
axis="columns",
)
) # 先计算奖励金额在根据机构分配比例拆分
.assign(总部="总部")
.assign(
# 整合机构
机构名称=lambda dataframe: dataframe.apply(
lambda x: [x["落地机构"], x["出单机构"], x["总部"]], axis="columns"
),
# 整合分配比例
分配比例=lambda dataframe: dataframe.apply(
lambda x: [
x["落地机构分配比例"],
x["出单机构分配比例"],
x["总部分配比例"],
],
axis="columns",
),
)
.explode(["机构名称", "分配比例"])
.assign(
分配后奖励金额=lambda dataframe: dataframe.apply(
lambda row: (row["奖励金额"] * Decimal(row["分配比例"]) / 100).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
),
axis="columns",
),
)
.assign(
机构=lambda dataframe: dataframe["机构名称"].apply(
lambda cell: mapped_as_institution_name(cell)
)
)
.loc[
lambda dataframe: (dataframe["机构"] != "总部") & (dataframe["分配比例"] != "0")
] # 过滤总部
.sort_values(by="分配后奖励金额", ascending=False)
.reset_index(drop=True)
)[
[
"保单编号",
"投保公司",
"保险总公司",
"保险分公司",
"发卡金额",
"消费金额",
"转化率",
"奖励比例",
"奖励金额",
"机构",
"分配比例",
"分配后奖励金额",
]
]
save_as_workbook(
workbook_name="机构绩效试算.xlsx",
worksheets=[
("大区年终薪酬", regional_year_end_bonus),
("机构年终薪酬", institutional_year_end_bonus),
("自主经营发卡奖励", card_issuance_reward),
("重点存量业务消费提升奖励", increase_reward),
("新增业务消费奖励", new_reward),
],
)