251029更新

This commit is contained in:
marslbr 2025-10-29 18:08:49 +08:00
parent 376d8448a7
commit 73511f73cc
1 changed files with 322 additions and 357 deletions

View File

@ -1,6 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
if __name__ == "__main__":
""" """
基于RFM模型生成数据分析报告 基于RFM模型生成数据分析报告
@ -8,61 +7,42 @@ if __name__ == "__main__":
# 导入模块 # 导入模块
import pandas import statistics
from datetime import datetime from datetime import datetime
from decimal import Decimal, ROUND_HALF_UP from decimal import Decimal, ROUND_HALF_UP
import statistics import pandas
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
from utils.client import MySQLClient from utils.client import MySQLClient
from utils.pandas_extension import DrawAsHTML from utils.pandas_extension import DrawAsHTML
# 函数说明根据RFM编码映射为客户分类 # 函数说明根据RFM编码映射为客户分类
def map_classification(r_encoded, f_encoded, m_encoded): def map_classification(r_encoded, f_encoded, m_encoded):
# 就R、F、M指标构建独热编码并匹配客户分类 # 就R、F、M指标构建独热编码并匹配客户分类
match f"{r_encoded}{f_encoded}{m_encoded}": match f"{r_encoded}{f_encoded}{m_encoded}":
case "000": case "000":
classification = "流失客户" classification = "流失客户"
case "010": case "010":
classification = "一般维持客户" classification = "一般维持客户"
case "100": case "100":
classification = "新客户" classification = "新客户"
case "110": case "110":
classification = "潜力客户" classification = "潜力客户"
case "001": case "001":
classification = "重要挽留客户" classification = "重要挽留客户"
case "101": case "101":
classification = "重要深耕客户" classification = "重要深耕客户"
case "011": case "011":
classification = "重要唤回客户" classification = "重要唤回客户"
case "111": case "111":
classification = "重要价值客户" classification = "重要价值客户"
# noinspection PyUnboundLocalVariable # noinspection PyUnboundLocalVariable
return classification return classification
print("1 加载数据集...", end="") print("1 加载数据集...", end="")
client = MySQLClient(database="data_analysis") client = MySQLClient(database="data_analysis")
@ -109,9 +89,7 @@ if __name__ == "__main__":
), ),
F=( F=(
"客户ID", "客户ID",
lambda x: Decimal(len(x)).quantize( lambda x: Decimal(len(x)).quantize(Decimal("0"), rounding=ROUND_HALF_UP),
Decimal("0"), rounding=ROUND_HALF_UP
),
), ),
M=( M=(
"交易金额", "交易金额",
@ -136,15 +114,9 @@ if __name__ == "__main__":
# R、F和M的平均数使用STATISTICS.MEAN统计平均值保证精度 # R、F和M的平均数使用STATISTICS.MEAN统计平均值保证精度
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
means = { means = {
"R": statistics.mean(rfm["R"]).quantize( "R": statistics.mean(rfm["R"]).quantize(Decimal("0.00"), rounding=ROUND_HALF_UP),
Decimal("0.00"), rounding=ROUND_HALF_UP "F": statistics.mean(rfm["F"]).quantize(Decimal("0.00"), rounding=ROUND_HALF_UP),
), "M": statistics.mean(rfm["M"]).quantize(Decimal("0.00"), rounding=ROUND_HALF_UP),
"F": statistics.mean(rfm["F"]).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
),
"M": statistics.mean(rfm["M"]).quantize(
Decimal("0.00"), rounding=ROUND_HALF_UP
),
} }
rfm = rfm.assign( rfm = rfm.assign(
@ -158,9 +130,7 @@ if __name__ == "__main__":
) )
) )
dataframe = dataframe.merge( dataframe = dataframe.merge(right=rfm[["客户ID", "客户分类"]], on="客户ID", how="left")
right=rfm[["客户ID", "客户分类"]], on="客户ID", how="left"
)
print("已完成") print("已完成")
@ -236,9 +206,7 @@ if __name__ == "__main__":
file_name="交易金额占比.html", file_name="交易金额占比.html",
) )
report_backward = pandas.DataFrame( report_backward = pandas.DataFrame(data=[], columns=["客户分类", "窗口期", "客户数"])
data=[], columns=["客户分类", "窗口期", "客户数"]
)
for customer_type in customer_types["客户分类"]: for customer_type in customer_types["客户分类"]:
@ -253,9 +221,7 @@ if __name__ == "__main__":
).start_time.date() ).start_time.date()
# 窗口期止期 # 窗口期止期
period_end = pandas.Period( period_end = pandas.Period(value=f"2013-{month:02d}", freq="M").end_time.date()
value=f"2013-{month:02d}", freq="M"
).end_time.date()
# 指定客户分类窗口期内客户数 # 指定客户分类窗口期内客户数
customer_counts = dataframe.loc[ customer_counts = dataframe.loc[
@ -392,7 +358,6 @@ if __name__ == "__main__":
) )
with open("rfm_report.html", "w", encoding="utf8") as file: with open("rfm_report.html", "w", encoding="utf8") as file:
file.write(rfm_report) file.write(rfm_report)
print("已完成") print("已完成")