
简介这是一份面向计算机、自动化等相关专业学生的Python电商平台数据分析系统完整源码包自带使用教程说明可直接用于课程大作业、期末课程设计或毕业设计。项目严格按“读取数据—数据处理—数据分析及可视化—数据分析报告”的完整流程组织覆盖2020年订单数据提取、异常值清理例如支付时间间隔过长、订单金额与支付金额为负等并实现了销售额趋势、用户复购率、用户行为分析、RFM客户分群、渠道来源贡献等相对完整的分析模块。资源内共30个文件包含7个Python脚本、19张可视化结果图、1份项目说明文档及3个编译缓存文件压缩包仅1.68MB脚本间分工清晰销售、复购、用户、RFM、渠道等分析均可对照结果图查看结论项目说明文档还提供了字段字典、业务含义与分析思路备注。目前已有883人浏览学习所有代码经过运行验证适合希望快速掌握电商数据分析完整流程、需要可复用工程代码的初中级学习者参考。1. 电商平台数据分析系统源码 使用说明这才是一份课程大作业该有的骨架如果你是冲着「Python课程大作业电商平台数据分析系统源码使用教程说明.zip」来的说明你现在大概率需要一套不用从零开始的 Python 数据分析项目骨架。这套资源里打包的不是零散代码而是一整套电商平台分析链路SalesTrend.py、RepurchaseRate.py、UserBehavior.py、ChanelSource.py、RFM.py 五个核心模块加上项目说明.md 和一批分析图片覆盖从订单表读取、脏数据清洗、2020 年数据提取到销售趋势、复购率、用户行为、渠道来源、RFM 分层五个分析视角最后能直接拼出一份课程设计报告。它特别适合计算机、自动化等专业学生拿来当期末课程设计或课程大作业的底子同样也能作为毕业设计的数据分析部分直接复用。下面按我拆项目源码的习惯把读取、清洗、分析、可视化、踩坑这条链路完整拆开。2. 数据读取与清洗从字段字典到 2020 年订单提取全流程这套分析的第一行输入是一张典型的电商订单表。项目说明把字段给得很清楚id、orderID、userID、goodsID、orderAmount、payment、chanelID、platformType、orderTime、payTime、chargeback。看到这张表第一反应不是急着写 groupby而是先建字段字典把每个字段能回答什么问题对齐。我在动手前会先确认五件事订单金额用 orderAmount 还是 payment、时间维度用 orderTime 还是 payTime、用户维度怎么去重、渠道维度会不会有缺失值、chargeback 是退单还是拒付标记。这五件事不定清楚后面所有聚合结果都是空中楼阁。2.1 字段字典拿到数据后先建一张映射表下面这张表是项目说明里字段的中英文对照我按分析用途加了一列方便你写报告时直接引用字段中文含义分析用途id编号主键行级去重orderID订单编号订单数统计同一订单多条商品时不能直接 countuserID用户编号用户维度聚合复购率、RFM 的唯一标识goodsID商品编号商品维度分析orderAmount订单金额GMV销售趋势的分子payment支付金额真实收入口径和订单金额对比可做支付转化分析chanelID渠道编号渠道来源分析platformType平台类型平台对比分析orderTime下单时间销售时间序列趋势分析的横轴payTime支付时间支付时滞计算chargeback退单拒付订单质量风险指标这张表的价值在写报告时特别明显。答辩时老师最常问的就是「你这个指标是怎么定义的」字段字典就是回答这个问题的底稿。比如 GMV 用 orderAmount 算、实际收入用 payment 算两个口径放一起还能算出支付转化率这些都是报告里能展开写的内容不是简单贴一张聚合表就完事。2.2 用 pandas 加载数据并统一时间字段格式项目里的主脚本 PythonDataAnalyse.py 承担数据加载和预览的职责。读取时我习惯把列名显式指定避免 Excel 导出的表头带空格或 BOM 前缀。import pandas as pd df pd.read_csv(sales_data.csv, encodinggbk) df.columns [id, orderID, userID, goodsID, orderAmount, payment, chanelID, platformType, orderTime, payTime, chargeback] df[orderTime] pd.to_datetime(df[orderTime]) df[payTime] pd.to_datetime(df[payTime]) print(df.info()) print(df.head())这一段做了三件事按路径读入 CSV把 11 个字段的中文表头重命名为统一英文名把时间字段从字符串转成 pandas 的 datetime 类型。转类型这步很关键后面的.dt.year、.dt.hour都要依赖它。encodinggbk是针对国内课程数据集最常见的编码如果读取时报UnicodeDecodeError换成utf-8-sig再试。提示如果数据源是 xlsx 文件把read_csv换成read_excel并提前pip install openpyxl有缺失值可以先跑df.isnull().sum()看分布再决定填充还是删除。2.3 提取 2020 年数据并清洗业务脏数据拿到完整数据后第一步是按业务需要提取 2020 年数据。这一步原项目用的条件很简单df_2020 df[df[orderTime].dt.year 2020].copy() print(f2020 年订单量: {len(df_2020)}).dt.year是 pandas 时间序列访问器能直接取年份。这里必须加.copy()否则后面 df_2020 的修改会触发链式赋值的 SettingWithCopyWarning排查起来非常让人头疼。接着是清洗。项目说明里明确提到了两类业务脏数据支付时间间隔过长的记录、订单金额或支付金额为负的记录。我按照这个口径写一套掩码过滤df_tmp df_2020.copy() df_tmp[pay_gap] df_tmp[payTime] - df_tmp[orderTime] mask_gap df_tmp[pay_gap] pd.Timedelta(0) mask_gap_short df_tmp[pay_gap] pd.Timedelta(hours24) mask_amount (df_tmp[orderAmount] 0) (df_tmp[payment] 0) before_cnt len(df_tmp) df_clean df_tmp[mask_gap mask_gap_short mask_amount].copy() after_cnt len(df_clean) print(f清洗后剩余记录数: {after_cnt}) print(f清洗比例: {1 - after_cnt / before_cnt:.2%})第一条规则要求支付时间必须晚于下单时间否则逻辑上不成立第二条规则把支付与下单间隔超过 24 小时的订单挡在分析之外这类订单大概率是测试数据或异常支付第三条规则剔除金额为负的数据。三条规则用连接表示同时满足才保留。24 小时这个阈值是项目给出的业务口径你可以按场景调整但调整后要在报告里注明否则答辩时老师会追问清洗逻辑的依据。注意mask 筛选统一用而不是and。and会触发 pandas 的布尔值歧义报错这条规则在多个条件叠加时尤其重要。清洗完成后的脏数据分布项目里专门存了一张脏数据处理方式.png这张图放进报告可以完整展示「原始数据 → 规则定义 → 清洗结果」的过程属于课程设计里很加分的部分。3. 五个分析模块逐个拆SalesTrend、复购率、用户行为、渠道来源、RFM正式分析阶段我按项目的模块顺序梳理先用 SalesTrend.py 确定销售大盘再用 ChanelSource.py 看流量从哪里来接着用 UserBehavior.py 看用户什么时候来用 RepurchaseRate.py 看用户会不会再来最后用 RFM.py 回答哪些用户最值得运营。这个顺序也是报告里最好的行文结构先宏观后微观先规模后质量。3.1 SalesTrend.py月度 GMV 与订单量趋势销售趋势分析是整份报告的第一张图通常输出月 GMV、月订单量数据粒度够细还可以做日趋势。df_clean[month] df_clean[orderTime].dt.to_period(M) monthly_trend df_clean.groupby(month).agg( order_cnt(orderID, count), gmv(orderAmount, sum), revenue(payment, sum) ).reset_index() monthly_trend[month] monthly_trend[month].astype(str) print(monthly_trend)to_period(M)把时间归一到月份这样 2020-01 和 2021-01 不会被混淆。groupby后同时聚出订单量、GMV、实际支付三个口径一张表就能看清收入转化。astype(str)是为画图准备的否则 matplotlib 对 Period 对象经常不识别。参数上有两个点要小心。第一count(orderID)在数据是订单明细级时会重复统计同一订单多件商品的情况如果你的表已经是一行一个订单count 没问题如果是一行一件商品需要先用df_clean.drop_duplicates(orderID)再统计订单量。第二聚合口径决定报告结论orderAmount 看 GMVpayment 看实际收入两者差值就是未支付金额这个差值可以单独算一列放进报告。3.2 RepurchaseRate.py复购率的分子分母必须口径统一复购率是电商报告里最容易被质疑的指标因为定义方式太多了。项目这段代码用的是「复购用户占比」口径user_order_cnt df_clean.groupby(userID)[orderID].nunique() repurchase_rate (user_order_cnt 1).mean() print(f复购率: {repurchase_rate:.2%}) df_clean df_clean.sort_values(orderTime) df_clean[order_seq] df_clean.groupby(userID).cumcount() 1 df_clean[is_repurchase] df_clean[order_seq] 1groupby(userID).nunique()计算每个用户的独立订单数(user_order_cnt 1).mean()直接算出「下单次数大于 1 的用户 / 总购买用户」的比例这是最简洁的用户维度复购率。cumcount()给每个用户的订单按时间排序编号方便识别每一次下单是不是复购也能用来算订单维度的复购率。口径上要特别说明nunique对重复的订单号去重防止同一订单多行被算成多次购买如果用复购订单数除以总订单数需要把mean()作用在is_repurchase这一列上。两种口径数字可能差异很大写报告时必须标注用的是哪一种否则答辩时很容易被抓住漏洞。3.3 UserBehavior.py 与 UserBehavior2.py下单时段与周活跃分布用户行为分析的两个文件一个偏向小时维度的下单分布一个做星期粒度两者合起来才能完整描述用户的活跃周期。df_clean[hour] df_clean[orderTime].dt.hour hourly_orders df_clean.groupby(hour)[orderID].count() df_clean[weekday] df_clean[orderTime].dt.dayofweek weekday_orders df_clean.groupby(weekday)[orderID].count() peak_hour hourly_orders.idxmax() peak_weekday weekday_orders.idxmax() print(f下单高峰时段: {peak_hour} 点, 最活跃星期: {peak_weekday})hour 是 0-23 的整数weekday 是 0-6 的整数周一为 0。idxmax()返回最大值所在的索引直接定位峰值时段和峰值星期。这类分析的结论通常长这样「晚上 20-22 点是下单高峰周末订单量明显高于工作日」把两条结论连起来就能解释销售波动的来源。这里不能只算均值均值会把峰值磨平。比如上午订单稀疏、晚上订单密集均值可能落在下午看起来「不温不火」但实际上业务节奏非常清晰。报告里要多展示分布形态少展示汇总统计量。3.4 ChanelSource.py渠道 GMV 与拒付率一起看渠道分析的关键不是只看 GMV 排名而是把 GMV 和拒付率放在同一张表里观察。channel_stats df_clean.groupby(chanelID).astype(str).agg( order_cnt(orderID, count), gmv(orderAmount, sum), revenue(payment, sum), chargeback_cnt(chargeback, sum) ) channel_stats[chargeback_rate] channel_stats[chargeback_cnt] / channel_stats[order_cnt] channel_stats channel_stats.sort_values(gmv, ascendingFalse) print(channel_stats)一个渠道如果 GMV 很高但 chargeback_rate 也高说明它的订单质量存在问题流量很可能是补贴拉来的。.sort_values(gmv, ascendingFalse)让高 GMV 渠道排在最前先看规模再看质量。这比单画一个饼图有说服力得多也是报告里最重要的业务结论之一。需要注意 chargeback 字段的类型。如果原始数据是「是/否」或「退单/正常」之类的文本必须先用map转成 0/1才能用sum()统计拒付数量。chanelID 如果是数字类型建议astype(str)后再分组避免「渠道 1」和「渠道 01」被拆成两个 key。3.5 RFM.py用户分层模型的阈值如何收敛RFM 是这套代码里最值得单独讲的部分。R 代表最近一次下单距今天数F 代表下单频次M 代表累计支付金额。先算基础特征ref_date df_clean[orderTime].max() pd.Timedelta(days1) rfm df_clean.groupby(userID).agg( R(orderTime, lambda x: (ref_date - x.max()).days), F(orderID, nunique), M(payment, sum) ) print(rfm.describe())ref_date取全部订单时间的最大值再加一天确保每个用户的 R 都是正数不会出现活跃用户 R0 导致分档异常的情况。lambda x: (ref_date - x.max()).days是计算每个用户最近一次购买距离参考日期多少天天数越小越活跃。F 用 nunique 统计独立订单数M 用 sum 统计累计支付金额。接下来是打分。项目代码如果直接用固定阈值我一般会建议先看数据分布再切分rfm[R_level] pd.qcut(rfm[R], 3, labels[活跃, 一般, 沉睡]) rfm[F_level] pd.qcut(rfm[F], 3, labels[低频, 中频, 高频]) rfm[M_level] pd.qcut(rfm[M], 3, labels[低客单, 中客单, 高客单]) print(rfm.groupby([R_level, F_level, M_level]).size())pd.qcut按分位数把数据三等分保证每档样本量接近不会出现某一档占 80% 的失衡情况。注意 R 的方向R 越小表示用户越近期活跃所以第一个 label 是「活跃」和后两个指标的标签方向相反。如果数据里有大量重复的边界值qcut会报Bin edges must be unique这时加参数duplicatesdrop即可。RFM 分层的最终输出一般落在 RFM.png 里配合用户分布散点图展示。报告里不要只贴分层结果要写明每个档位的 R/F/M 数值范围并给每档一句运营建议比如「沉睡高客单用户需要召回活跃中频用户需要提升客单价」。4. 可视化输出与报告组织把图片素材变成论文插图数据分析项目只出表格不出图在课程设计里等于白做。压缩包里的 picture 目录和一批 png 文件是项目说明.md 给整套分析配的图表集。拆这类资源时我发现最有价值的不是单张图多好看而是作者为什么存这么多图、每张图在报告里承担什么角色。这一章从图表文件讲到报告组织。4.1 图片文件与模块的对应关系别把所有图堆在一起先给出一张映射表注意文件和图片不完全是严格一一对应有的模块会输出多张图而方法图不一定来自分析结果图片文件预期内容对应分析模块t1.png月度 GMV / 订单量趋势图SalesTrend.py001.png / 002.png数据读取与预览截图PythonDataAnalyse.py003.png / 004.png清洗前后的对比或比例图脏数据处理流程005.png / 006.png复购率或用户分布结果图RepurchaseRate.py007.png / 008.png / 009.png小时、星期维度的用户行为分布UserBehavior.py / UserBehavior2.py010.png / 011.png渠道来源分析与平台对比ChanelSource.pyt2.png / t3.png 等分模块分析的中间结果图各分析模块RFM.pngRFM 三维分层结果RFM.py脏数据处理方式.png清洗规则流程说明数据处理章节这张表教会你的是「图怎么进报告」。课程设计报告的配图组织我的习惯是方法图脏数据处理方式.png放在数据清洗章节结果图趋势、渠道、RFM放在对应分析章节代码截图放在附录。方法图与结果图混在一起堆会让老师觉得你只是把图片平铺没有行文逻辑。4.2 报告里每张图怎么解释从指标定义到下一步建议一张图放进报告不能只写「由上图可知」要写三层趋势是什么、原因可能是什么、下一步怎么做。比如月度销售趋势图对应的文字可以是「2020 年 6 月和 11 月出现两个 GMV 高峰6 月对应年中大促11 月对应双十一与电商平台常见促销节奏一致建议后续运营资源向大促前置投放倾斜」。这类结论在课程设计里最能拿分因为你让老师看出你真的理解业务而不是只会跑代码。渠道图对应的解释可以是「渠道 A 贡献最高 GMV但拒付率也高于平均水平建议关注该渠道订单风控不建议把渠道 GMV 占比作为唯一 KPI」。RFM 图则要回答「哪一类用户贡献多少 GMV、应该采取什么触达策略」。每一张结果图都按「指标定义 → 图表展示 → 业务解释 → 下一步建议」四段式来写报告结构自然饱满。4.3 中文字体与高清导出matplotlib 的全局配置课程设计里的图往往要打印或导出 PDF分辨率太低直接糊。我一般在所有绘图脚本开头统一写一段配置import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, PingFang SC] plt.rcParams[axes.unicode_minus] False plt.rcParams[figure.dpi] 150 plt.rcParams[savefig.dpi] 300 plt.rcParams[figure.figsize] (10, 6)这一段解决了三个高频问题font.sans-serif设置多字体回退SimHei 在 Windows 可用macOS 上换 PingFang SCaxes.unicode_minus必须为 False否则坐标轴的负号会显示成方块savefig.dpi300保证插图放进 Word 里放大仍然清晰。150 的 figure.dpi 屏幕显示足够300 的保存 DPI 应对论文插图绰绰有余。具体保存时显式传参比依赖全局属性更稳fig, ax plt.subplots(figsize(10, 6)) ax.plot(monthly_trend[month], monthly_trend[gmv], markero, labelGMV) ax.plot(monthly_trend[month], monthly_trend[revenue], markers, label支付金额) ax.set_title(2020 年电商平台月度销售趋势) ax.set_xlabel(月份) ax.set_ylabel(金额) ax.legend() plt.xticks(rotation45) fig.tight_layout() fig.savefig(t1.png, bbox_inchestight) plt.close(fig)bbox_inchestight避免坐标轴被裁切rotation45让横轴月份不挤成一条黑线plt.close(fig)释放内存。如果循环画十张图不关图内存会一路攀升脚本跑久了明显变慢。这套配置当模板用基本不会翻车。5. 复现避坑清单从 pycache 到中文字体的血泪经验资源是能直接跑的但「能跑」建立在环境一致的前提下。压缩包里的__pycache__目录放着SalesTrend.cpython-37.pyc这个细节很多人解压时根本不会在意直到运行报错才发现问题。这一章把复现这套数据分析项目时踩过的坑按「现象 → 原因 → 解决」列出来每一条都对应真实翻车现场。5.1 Python 3.7 的 pycache 文件在新环境里报错现象解压后直接执行python SalesTrend.py报SyntaxError: invalid syntax或ModuleNotFoundError但资源作者明明标着「代码经过运行验证」。原因__pycache__里的SalesTrend.cpython-37.pyc是 Python 3.7 编译的字节码。pyc 与 Python 小版本强绑定3.7 的 pyc 在 3.8/3.9/3.11 环境里不会自动重新编译于是报错直接顶到脸上。.py 本身没问题环境不匹配而已。解决先删掉整个__pycache__目录再重新执行 .pyrm -rf __pycache__ python SalesTrend.pyWindows 的普通 CMD 里rm -rf不可用用rmdir /s /q __pycache__。删除后让 Python 重新编译生成当前版本的 pyc再也没报过这个错。5.2 CSV 编码不一致导致读取失败现象pandas 读数据文件时直接报UnicodeDecodeError: utf-8 codec cant decode byte ...。原因中文环境下的 Excel 另存 CSV 默认用 GBK/GB2312 编码而read_csv默认按 utf-8 解码。编码对不上读取必然失败。解决先试encodinggbk再试encodingutf-8-sig。utf-8-sig能自动去掉 Excel 写 UTF-8 时加在文件头的 BOM如果你发现表头第一列名称总是带着奇怪的\ufeff用utf-8-sig就能解决。5.3 matplotlib 中文乱码标题全是方块现象代码跑通、图也出了但中文标题、坐标轴、图例全是「□□□」。原因matplotlib 默认字体集合里没有中文字体。Windows 默认靠 SimHeimacOS 靠 PingFang SC不指定就是方块。解决在所有绘图代码前加两行配置plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, PingFang SC] plt.rcParams[axes.unicode_minus] Falseaxes.unicode_minus这一行最容易被忽略它的作用是防止负号显示成方块是 matplotlib 中文字体坑里最大的隐藏项。5.4 时间字段格式混杂to_datetime 解析失败现象df_2020 df[df[orderTime].dt.year 2020]报AttributeError: Series object has no attribute dt说明 orderTime 还是 object 类型或者直接报日期解析错误。原因订单时间字段格式不统一有的行是2020-01-01 12:00:00有的是2020/01/01甚至带中文「年月日」。pandas 对混合格式识别不稳定解析成 object 或 NaT。解决手动指定 format 并用 errors 兜底df[orderTime] pd.to_datetime( df[orderTime], format%Y-%m-%d %H:%M:%S, errorscoerce ) df df.dropna(subset[orderTime])errorscoerce把无法解析的行变成 NaTdropna再将脏行丢弃。注意如果设置后清洗掉的行数突然增大先看原始数据格式确认不是把所有有效行都误杀了。5.5 RFM 固定阈值导致分层失衡现象RFM 打分后某一档用户数量占 80%其他档空到没法看分层图完全失去参考价值。原因RFM 阈值用了固定值比如 R30 算活跃、F5 算高频。不同数据集的订单周期和用户频次差异极大套用别的项目阈值自然失衡。解决先用describe()看分布再用分位数切分print(rfm.describe()) rfm[R_level] pd.qcut(rfm[R], 3, labels[活跃, 一般, 沉睡], duplicatesdrop) rfm[F_level] pd.qcut(rfm[F], 3, labels[低频, 中频, 高频], duplicatesdrop) rfm[M_level] pd.qcut(rfm[M], 3, labels[低客单, 中客单, 高客单], duplicatesdrop)pd.qcut按分位数三等分让每档区间内用户数接近。代价是边界阈值由数据自己决定不同批次数据切出来的档位含义会有变化写报告时记得把每档对应的 R/F/M 范围列出来不要只贴标签。6. 把这套代码改成自己的项目换数据、调阈值、加指标把别人的课程设计变成自己的关键不是改文件名而是改三处数据源、分析参数、业务结论。6.1 替换数据集时先过三关检查第一道检查列名。原项目字段是英文你拿到的新数据集很可能是中文列名或完全不同的英文命名先做一层 rename 映射把新数据对齐到 id、orderID、userID、orderAmount、payment、chanelID、platformType、orderTime、payTime、chargeback 这套体系上五个分析模块才能跑通。第二道检查时间跨度。原项目只提取 2020 年数据如果你的数据集是 2021-2023 年把df[orderTime].dt.year 2020改成对应年份或者提取最近 12 个月。第三道检查缺失值。渠道编号和平台类型在真实数据里很容易出现空值用fillna(unknown)兜底而不是让 groupby 把空值直接丢掉。6.2 加一个新指标的最小代码模板课程设计想拿高分多一个「别人没算」的指标比把已有图重画一遍更有效。比如加一个支付转化率含义是支付金额占订单金额的比例df_clean[pay_ratio] df_clean[payment] / df_clean[orderAmount] pay_ratio_stats df_clean.groupby(chanelID)[pay_ratio].agg([mean, median]) print(pay_ratio_stats)把这个指标落到渠道维度就能回答「哪个渠道的下单用户真正掏了钱」与拒付率形成互补。换任何数据集这段代码只需要保证 payment 和 orderAmount 分母不为 0其余逻辑不用改。安装环境如果还卡在 Python 本身先按 python 安装教程把 3.8 及以上版本装好再pip install pandas matplotlib openpyxl三个库就能跑完整套脚本。跑通后结合项目说明.md 整理分析报告把这份笔记里的字段字典、清洗规则和各模块结论串进去就是一份能直接提交的课程设计。说实话我拆过不少课程大作业源码包这套项目的可贵之处在于模块划分干净、每一步输出都有图有解释不是丢一堆函数就完事。从那以后我每次拿到新数据集都会强制自己先走一遍「建字段字典 → 清洗验证 → 分模块出图 → 写业务解释」的流程这套流程帮我省下的 debug 时间远比想象中多。希望帮到你也祝你期末课程设计顺利答辩过关。本文还有配套的精品资源点击获取