简介:这是一套面向高校学生的Python电商平台数据分析系统完整项目,适用于期末大作业、课程设计及毕业设计场景,难度适中,评审得分达98分,内容经助教老师审定。项目围绕电商业务展开,涵盖销售趋势分析、复购率计算、用户行为分析、渠道来源统计及RFM用户分层等典型分析模块,帮助读者掌握从数据清洗到可视化呈现的完整流程。资源包共30个文件,约1.68MB,其中7个py源码文件承载核心分析逻辑,19个png图片用于展示分析结果与图表,另有pyc编译文件及README说明文档,便于快速理解项目结构与运行方式。目前已有197人学习关注。通过研读源码与配套文档,读者可获得一套可直接参考的高分项目方案,理解各分析模块的实现思路与脏数据处理方法,并借助可视化图表对照验证结果,为自身作业或设计提供清晰的结构参考与排错思路。
1. 电商数据分析大作业:从“能跑”到“高分”差在哪
每年期末,总有一批同学在群里问同一句话:“电商平台数据分析系统到底怎么做才能拿高分?”我见过太多交上去的版本——爬了几百条评论,画两张柱状图,README 写三行,最后分数卡在及格线。问题不在技术难度,而在于大多数人把它当“作业”而不是“项目”来做。一个能拿高分的 Python 大作业电商平台数据分析系统,核心不是模型多花哨,而是数据链路完整、分析维度有业务含义、文档说明能让老师三分钟看懂你做了什么。这篇笔记面向正在做课程设计或毕业设计的同学,也面向想用 Python 快速搭一套电商数据分析原型的开发者。我会把从数据采集、清洗、指标计算到可视化呈现的完整路径拆开讲,源码结构和文档说明的写法也会一并给出,照着做能少走至少两周弯路。
2. 先想清楚分析什么:电商数据指标体系的搭建逻辑
2.1 为什么不能上来就写爬虫
很多人拿到题目的第一反应是打开 requests 或 scrapy 开始抓数据,这是典型的翻车起点。电商平台数据分析系统的价值不在于数据量大小,而在于你选的指标能不能回答业务问题。老师看的是你有没有“分析思维”,不是爬了多少条。
我一般会先画一张指标地图,把电商场景拆成四个维度:用户维度(新增用户、活跃度、复购率)、商品维度(销量排名、品类占比、价格带分布)、交易维度(GMV、客单价、转化率)、时间维度(日/周/月趋势、促销期波动)。每个维度选 2 到 3 个可计算的指标,总共控制在 10 到 15 个,足够撑起一份高分作业。
选指标的原则是:能从你拿到的数据里算出来。比如你只有订单表,没有用户行为埋点,那“页面停留时长”就别写进去,否则答辩时被问“这个数怎么来的”会很难受。
2.2 数据源选型:公开数据集 vs 自采数据
数据来源决定了后续所有工作的复杂度。常见做法有三种:
| 数据源类型 | 获取方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 公开数据集 | Kaggle、天池、和鲸社区下载 | 字段完整、量级大、省时间 | 业务背景陌生、可能过时 | 时间紧、想专注分析 |
| 自采数据 | requests + BeautifulSoup 抓取 | 业务场景自选、可控 | 反爬、字段缺失、清洗量大 | 想体现工程能力 |
| 模拟生成 | Faker + 随机规则生成 | 完全可控、字段自定义 | 数据真实性差 | 演示流程、快速验证 |
我的建议是:如果时间充裕且想拿高分,用“公开数据集 + 少量自采”组合。公开数据集保证分析深度,自采数据体现你的工程能力。比如从 Kaggle 下载一份电商订单数据集做主分析,再写个小爬虫抓取某品类商品评论做情感分析补充。
2.3 用 pandas 做数据清洗的最小可复现流程
拿到数据后,80% 的时间会花在清洗上。下面是一个我常用的清洗模板,覆盖缺失值、异常值、格式统一三类问题:
import pandas as pd import numpy as np # 读取原始数据 df = pd.read_csv('ecommerce_orders.csv', encoding='utf-8') # 1. 查看整体情况 print(df.info()) print(df.describe()) print(df.isnull().sum()) # 2. 处理缺失值:数值列用中位数填充,类别列用众数填充 num_cols = df.select_dtypes(include=[np.number]).columns cat_cols = df.select_dtypes(include=['object']).columns for col in num_cols: df[col].fillna(df[col].median(), inplace=True) for col in cat_cols: df[col].fillna(df[col].mode()[0], inplace=True) # 3. 处理异常值:用 IQR 方法识别并替换 def replace_outliers(series): Q1 = series.quantile(0.25) Q3 = series.quantile(0.75) IQR = Q3 - Q1 lower = Q1 - 1.5 * IQR upper = Q3 + 1.5 * IQR return series.clip(lower, upper) for col in ['price', 'quantity', 'amount']: if col in df.columns: df[col] = replace_outliers(df[col]) # 4. 统一日期格式 df['order_date'] = pd.to_datetime(df['order_date'], errors='coerce') df.dropna(subset=['order_date'], inplace=True) # 5. 去重 df.drop_duplicates(subset=['order_id'], keep='first', inplace=True) print(f'清洗后数据量:{len(df)}') df.to_csv('cleaned_orders.csv', index=False)这段代码的逻辑是:先诊断再治疗。info()和isnull().sum()让你知道数据长什么样,然后按列类型分别处理缺失值。IQR 方法把超出 1.5 倍四分位距的值截断到边界,比直接删除温和,不会损失太多样本。日期列用errors='coerce'把无法解析的值变成 NaT 再删掉,避免后续时间序列分析报错。
参数方面,fillna的填充策略可以根据业务调整:如果缺失率超过 40%,建议直接删列而不是填充,否则引入的噪声比信息还多。clip的上下界系数 1.5 是统计学惯例,如果数据本身波动大可以放宽到 3。
提示:清洗完一定要保存一份中间结果,后续分析都基于清洗后的数据,避免每次从头跑。
3. 核心分析模块的代码实现:从指标计算到可视化
3.1 GMV、客单价、复购率的计算代码
指标体系搭好后,计算本身不难,难的是口径统一。下面是我常用的核心指标计算函数:
import pandas as pd def calc_core_metrics(df): """ 输入:清洗后的订单数据,包含 order_id, user_id, amount, order_date 输出:核心指标字典 """ # GMV:所有订单金额之和 gmv = df['amount'].sum() # 客单价:GMV / 去重用户数 unique_users = df['user_id'].nunique() avg_order_value = gmv / unique_users if unique_users > 0 else 0 # 复购率:下单次数 >= 2 的用户占比 user_order_counts = df.groupby('user_id')['order_id'].count() repeat_users = (user_order_counts >= 2).sum() repeat_rate = repeat_users / unique_users if unique_users > 0 else 0 # 月度 GMV 趋势 df['month'] = df['order_date'].dt.to_period('M') monthly_gmv = df.groupby('month')['amount'].sum() return { 'GMV': round(gmv, 2), '客单价': round(avg_order_value, 2), '复购率': f'{repeat_rate:.2%}', '月度GMV': monthly_gmv } metrics = calc_core_metrics(df) for k, v in metrics.items(): print(f'{k}: {v}')这里有几个容易出错的地方。客单价的分母到底是“下单用户数”还是“订单数”,不同平台口径不同,论文里要写清楚你用的是哪种。复购率的阈值是“>=2 次”还是“>=3 次”,也要在文档里说明。月度趋势用to_period('M')而不是dt.month,因为后者会把不同年份的同月合并,导致趋势失真。
3.2 用 matplotlib 和 pyecharts 做可视化呈现
可视化是老师第一眼看到的东西,直接决定印象分。静态图用 matplotlib,交互图用 pyecharts,两者结合最稳。
import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams['font.sans-serif'] = ['SimHei'] matplotlib.rcParams['axes.unicode_minus'] = False # 月度 GMV 趋势图 fig, ax = plt.subplots(figsize=(10, 5)) monthly = metrics['月度GMV'] ax.plot(monthly.index.astype(str), monthly.values, marker='o', linewidth=2) ax.set_title('月度 GMV 趋势', fontsize=14) ax.set_xlabel('月份') ax.set_ylabel('GMV(元)') ax.grid(axis='y', linestyle='--', alpha=0.5) plt.xticks(rotation=45) plt.tight_layout() plt.savefig('monthly_gmv.png', dpi=150) plt.show()中文字体那两行是血泪经验,不设置的话标题全是方块。dpi=150保证截图放进论文里不糊。tight_layout()防止标签被裁掉。
如果要加交互效果,pyecharts 的写法更简洁:
from pyecharts.charts import Bar, Pie from pyecharts import options as opts # 品类销售占比饼图 category_sales = df.groupby('category')['amount'].sum().sort_values(ascending=False).head(10) pie = ( Pie() .add('', [list(z) for z in zip(category_sales.index, category_sales.values)]) .set_global_opts(title_opts=opts.TitleOpts(title='品类销售占比 Top10')) .set_series_opts(label_opts=opts.LabelOpts(formatter='{b}: {d}%')) ) pie.render('category_pie.html')pyecharts 生成的是 HTML 文件,可以直接嵌入文档说明里,老师打开浏览器就能看,比静态截图加分。
3.3 用户分群:RFM 模型的简化实现
RFM 是电商分析的经典模型,但完整版对作业来说太重。我一般用简化版:只算 R(最近一次购买距今天数)和 F(购买频次),把用户分成四群。
# 计算 RFM snapshot_date = df['order_date'].max() + pd.Timedelta(days=1) rfm = df.groupby('user_id').agg({ 'order_date': lambda x: (snapshot_date - x.max()).days, 'order_id': 'count', 'amount': 'sum' }).rename(columns={'order_date': 'R', 'order_id': 'F', 'amount': 'M'}) # 按中位数分高低 rfm['R_level'] = rfm['R'].apply(lambda x: '高' if x <= rfm['R'].median() else '低') rfm['F_level'] = rfm['F'].apply(lambda x: '高' if x >= rfm['F'].median() else '低') # 分群 def segment(row): if row['R_level'] == '高' and row['F_level'] == '高': return '核心用户' elif row['R_level'] == '高' and row['F_level'] == '低': return '新用户' elif row['R_level'] == '低' and row['F_level'] == '高': return '流失预警' else: return '流失用户' rfm['segment'] = rfm.apply(segment, axis=1) print(rfm['segment'].value_counts())R 的阈值用中位数而不是固定天数,是因为不同数据集的时间跨度差异很大。分群逻辑可以根据业务调整,比如把“新用户”改成“潜力用户”,文档里解释清楚就行。
4. 避坑与排查:做电商数据分析大作业最容易翻车的 5 个地方
4.1 中文乱码:图表标题全是方块
现象:matplotlib 生成的图表标题、轴标签显示为方框或乱码。
原因:matplotlib 默认字体不支持中文,且未关闭 Unicode 负号显示。
解决:在绘图前加两行配置——matplotlib.rcParams['font.sans-serif'] = ['SimHei']和matplotlib.rcParams['axes.unicode_minus'] = False。如果系统没有 SimHei,换成Microsoft YaHei或WenQuanYi Micro Hei。Linux 环境下需要先确认字体已安装,用fc-list :lang=zh查看。
4.2 日期解析失败导致时间序列断裂
现象:pd.to_datetime报错或产生大量 NaT,月度趋势图中间缺了好几段。
原因:原始数据里日期格式不统一,有的用2024/1/5,有的用2024-01-05,还有的带时间戳。
解决:用pd.to_datetime(df['order_date'], format='mixed', errors='coerce')让 pandas 自动推断格式。如果还不行,先统一替换分隔符:df['order_date'] = df['order_date'].str.replace('/', '-')。处理完检查 NaT 比例,超过 10% 要考虑是不是数据源本身有问题。
4.3 内存溢出:数据量太大跑不动
现象:读取 CSV 时卡死或报 MemoryError,尤其是几十万条以上的订单数据。
原因:默认读取时 pandas 会把所有列加载为 object 或 int64,内存占用远超预期。
解决:读取时指定dtype和usecols,只加载需要的列;数值列用float32代替float64;类别列用category类型。分批读取用chunksize参数:
chunks = pd.read_csv('large_orders.csv', chunksize=50000, usecols=['order_id', 'user_id', 'amount', 'order_date']) df = pd.concat([chunk for chunk in chunks], ignore_index=True)4.4 指标口径不一致导致结论矛盾
现象:文档里写的 GMV 和图表里算出来的对不上,或者复购率和用户分群结果矛盾。
原因:不同模块用了不同的过滤条件,比如算 GMV 时没排除退款订单,算复购率时又排除了。
解决:在清洗阶段就定义好“有效订单”的规则,比如status == 'completed',然后所有分析模块统一用这个过滤后的数据集。建议在代码开头定义一个valid_df = df[df['status'] == 'completed'].copy(),后续全部基于valid_df操作。
4.5 文档说明写成代码注释堆砌
现象:文档说明里全是函数说明和参数列表,没有业务背景和分析结论,老师看不懂你想表达什么。
原因:把“文档”理解成了“代码说明书”,忽略了分析报告的本质。
解决:文档说明按“背景 → 数据来源 → 分析方法 → 核心发现 → 结论与建议”五段式写。每个图表下面用两三句话解释“这张图说明了什么”,而不是“这张图是用什么代码画的”。老师关心的是你的分析能力,不是你的编码能力。
5. 高分项目的文档说明怎么写:结构模板与源码组织
5.1 文档说明的五段式结构
一份能拿高分的文档说明,核心是让读者在三分钟内理解你的工作。我常用的结构是:
第一段:项目背景与目标(200 字左右)。说清楚你分析的是哪个电商场景,想回答什么问题。比如“本项目基于某平台 2023 年订单数据,分析用户购买行为与品类销售趋势,为运营策略提供数据支撑”。
第二段:数据来源与预处理(300 字左右)。说明数据从哪来、多少条、哪些字段、做了哪些清洗操作。附一张清洗前后的数据对比表。
第三段:分析方法与指标定义(400 字左右)。列出你用的分析模型和每个指标的计算口径。RFM 模型要写清楚 R、F、M 各自的定义和分群阈值。
第四段:核心发现(500 字左右)。这是最重要的部分。每个发现配一张图,图下面写结论。比如“从月度 GMV 趋势看,11 月出现明显峰值,与促销活动时间吻合”。
第五段:结论与建议(200 字左右)。基于发现给出可操作的建议,比如“建议对流失预警用户推送优惠券”。
5.2 源码目录组织与运行说明
源码结构清晰与否直接影响老师对你工程能力的判断。推荐按功能模块划分目录:
ecommerce_analysis/ ├── data/ │ ├── raw/ # 原始数据 │ └── cleaned/ # 清洗后数据 ├── src/ │ ├── data_loader.py # 数据读取与清洗 │ ├── metrics.py # 指标计算 │ ├── visualization.py # 图表生成 │ └── rfm_analysis.py # 用户分群 ├── output/ │ ├── figures/ # 生成的图表 │ └── reports/ # 分析报告 ├── main.py # 主入口 ├── requirements.txt # 依赖清单 └── README.md # 运行说明main.py里按顺序调用各模块,保证一条命令跑通全流程:
from src.data_loader import load_and_clean from src.metrics import calc_core_metrics from src.visualization import plot_monthly_gmv, plot_category_pie from src.rfm_analysis import run_rfm if __name__ == '__main__': df = load_and_clean('data/raw/orders.csv') metrics = calc_core_metrics(df) plot_monthly_gmv(metrics['月度GMV']) plot_category_pie(df) rfm_result = run_rfm(df) print('分析完成,图表已保存至 output/figures/')requirements.txt里锁定版本号,避免老师环境跑不起来:
pandas==2.1.0 matplotlib==3.8.0 pyecharts==2.0.4 numpy==1.26.05.3 让老师三分钟看懂你的项目
最后说一个技巧:在 README 最前面放一张“项目概览图”,用文字描述整个分析流程——数据从哪来、经过哪些处理、产出什么结果。老师翻到这一页就能建立全局认知,后面的细节他才有耐心看。
另外,图表文件命名要语义化,比如monthly_gmv_trend.png而不是figure1.png。文档里引用图表时用相对路径,保证整个文件夹拷贝到任何电脑都能打开。
6. 从作业到作品:三个让项目脱颖而出的进阶技巧
6.1 加一个简单的预测模块
在描述性分析基础上加一个预测,哪怕只是用线性回归预测下月 GMV,也能让项目从“分析”升级到“预测”。用sklearn的LinearRegression十行代码就能搞定:
from sklearn.linear_model import LinearRegression import numpy as np # 用前 N-1 个月预测第 N 个月 monthly = metrics['月度GMV'] X = np.arange(len(monthly)).reshape(-1, 1) y = monthly.values model = LinearRegression() model.fit(X[:-1], y[:-1]) next_month_pred = model.predict([[len(monthly)]]) print(f'下月 GMV 预测:{next_month_pred[0]:.2f}')注意在文档里说明这只是趋势外推,不考虑促销等突发因素,避免被追问时尴尬。
6.2 用 pyecharts 做交互式仪表盘
把多个图表整合到一个 HTML 页面里,用Page类组合:
from pyecharts.charts import Page page = Page(layout=Page.DraggablePageLayout) page.add(pie, bar, line) # 添加之前生成的图表对象 page.render('dashboard.html')老师打开浏览器就能交互查看,比静态截图印象分高很多。如果时间充裕,可以用pyecharts的Grid做多图联动。
6.3 文档里加一节“局限性与改进方向”
这一节看似减分,实则加分。主动指出项目的不足,比如“数据时间跨度仅三个月,无法分析年度趋势”“未考虑退款订单对 GMV 的影响”,然后给出改进思路。老师看到的是你的批判性思维,这比假装完美更能体现分析素养。
我做了这么多课程项目,最大的教训是:高分项目不是功能最多的那个,而是逻辑最自洽、文档最清晰的那个。把每个指标的口径写清楚,把每张图的结论说明白,把代码整理到别人能跑通,分数自然不会低。希望帮到你。
本文还有配套的精品资源,点击获取