简介:这是一份面向Python数据分析学习者及电商相关专业学生的实战示例源码,以天猫双十一美妆销售数据为对象,演示约400行代码完成数据清洗、聚合分析与可视化展示的核心流程,适合作为课程大作业、毕设参考或入门实践项目。资源包共含17个文件,大小5.08MB,主要包含Python脚本(.py)、Jupyter Notebook分析文档(.ipynb)、HTML渲染结果、Excel数据表(.xlsx)及CSV原始数据等,兼顾源码、过程记录与结果呈现,便于对照学习。目前已有146人次学习下载。源码不仅覆盖pandas数据处理与matplotlib绘图,还涉及数据文件组织与工程化配置。借助完整的.ipynb和同步生成的.html,读者可一步步查看从读入CSV、清洗异常值到按品牌/类别绘制直方图、折线图的全过程;同时也能借此理解电商数据分析项目的目录结构与流程拆分方式,整体是一个可直接运行、可迁移到其他电商数据集的实用型小项目。 拿到这个项目标题的时候我就已经在笑了——双十一美妆数据分析,这几乎是每个学Python数据分析的人都绕不过去的“成人礼”。天猫双十一的美妆销售数据,字段丰富、业务含义直观、可视化发挥空间大,难度又刚好卡在大学课程作业和初级数据分析师入门之间,所以这个题材出现在大作业里一点都不意外。我最初接触这个项目的时候还是在校期间,代码写得比现在啰嗦一倍不止,后来陆陆续续帮别人看过几个类似项目,才慢慢知道一套400行左右的代码该把力气花在哪。
这篇文章就按一个“刚拿到这个项目、准备动手复现”的视角来聊。我会把整个项目的结构设计、数据清洗、可视化呈现、答辩常见提问全部串一遍,最后附上这个题材最容易踩进去的几个坑。
1. 项目整体设计与核心思路:为什么恰好是400行
先给还没打开压缩包的同学一个预判。这类双十一美妆数据分析项目,通常的构成是这样的:
data/ double11_makeup.xlsx # 原始数据 output/ top10_brands.png # 品牌销量/销售额TOP10 price_distribution.png # 价格带分布图 category_share.png # 品类结构图 trend_chart.png # 销量/销售额趋势图 src/ utils.py # 数据加载与清洗 analysis.py # 核心统计逻辑 plots.py # 可视化封装 main.py # 主入口一个核心的认知是:大作业项目的骨架比代码堆砌重要得多。400行的体量刚刚好,多一点显得堆砌,少一点显得单薄。这份代码要能把“读数据→清洗→分析→输出图表”整条链路跑通,同时让任何一名评委老师一眼看出这是“会写代码的人写的”,而不是“把教程抄了一遍”。
我帮几十个同学审过类似项目后,发现拿高分的关键不在模型多高级,而在于三件事:分析维度的业务合理性、图表的信息密度、以及代码能不能一键从头跑到尾。这三个标准对应的技术选型,锚定的就是pandas + matplotlib这套基础三件套。选matplotlib而不是pyecharts或者plotly,不是因为别的可视化库不好,而是matplotlib在作业场景里足够稳,中文字体配置一次后就全程可控,输出静态图直接贴论文和答辩PPT都方便,不会出现“答辩时图表库加载不出来”这种让人血压拉满的事故。
1.1 为什么这个项目适合作为数据分析练手
双十一美妆数据有一个很特殊的地方:它几乎是“最接近真实业务场景的演示数据”。对比网上下载的泰坦尼克号、鸢尾花这类练手数据集,美妆电商数据的每一列都有直接的商业含义。品牌、商品名、价格、月销量、总销售额、店铺类型,这六类字段能支撑起至少六个方向的分析:
- 品牌维度:哪些品牌是头部玩家,哪些品牌增速最快
- 价格维度:走量的是平价线还是高端线,降价空间在哪
- 商品维度:爆款长什么样,标题里哪些关键词出现频率高
- 店铺维度:旗舰店vs专营店vs海外店,哪一种形态效率更高
- 品类维度:护肤、彩妆、个护、香水,谁占大头
- 关联维度:价格和销量之间的弹性关系,优惠力度有没有真正拉动销量
这六类分析对应的都是真实的电商运营问题。我见过不少同学的作业只画了三四张图就交上去,很可惜,第一张图到第六张图之间体现的思维深度差异会直接反映在分数上。
1.2 基于原始数据的分析架构设计
拿到压缩包之后,我建议你别急着看代码,先把数据和主流程理一遍。典型的主流程是:
- 读取Excel数据,用
pd.read_excel或pd.read_csv,这一步重点检查数据规模和字段类型 - 数据清洗:处理缺失值、格式统一、去重、异常值剔除
- 数据规整:按分析维度用
groupby聚合,必要时用pd.cut切分价格带 - 可视化:每个分析维度对应一张图表,轮流产出
- 业务解读:在代码注释或调研报告里写明每张图反映了什么业务现象
这个流程先在大脑里跑通,再去看代码,你会立刻明白每一段代码存在的理由。因为这类项目基本不涉及预测和建模,本质是“用合适的组图方法配合业务理解做信息提取”,所以核心的代码量分布在数据清洗和可视化里,统计部分反而是最轻的,通常就是groupby + agg + sort_values三连。
2. 数据清洗与预处理:这个环节决定了项目成败的一半
很多同学拿到的原始数据,大概率不是干干净净躺在那里的。我见过最离谱的一次,Excel文件里有合并单元格、有“万人团”之类的兼职文案混进数值列、还有品牌名一会儿叫“兰蔻”一会儿叫“Lancome”的奇葩情况。所以数据清洗在双十一美妆这个题材里,不是微不足道的一步,而是优先级最高的一步。
2.1 字段解读与数据类型调整
一份标准的美妆销售数据,常见字段如下:
| 字段名 | 示例 | 数据类型 | 备注 |
|---|---|---|---|
| 品牌 | 欧莱雅 | 字符串 | 清洗时要注意大小写、中英文混用 |
| 商品名 | 欧莱雅复颜玻尿酸水乳套装 | 字符串 | 可以用来做词频分析 |
| 价格 | 299 | 数值/字符串 | 可能带“¥”“元”等字符 |
| 月销量 | 5万+ | 字符串 | 必须处理“万+”这种格式 |
| 总销售额 | 1495万 | 字符串 | 需根据单位换算为数值 |
| 店铺类型 | 天猫旗舰店 | 字符串 | 可能有“海外旗舰店”“专卖店”等多种形态 |
刚加载进来的时候,价格、月销量这类字段经常被识别成字符串,因为原始数据里混入了“万”、“+”、“¥”这类符号。这时候pd.to_numeric配合errors='coerce'就是最常用的招数:
import pandas as pd df = pd.read_excel('data/double11_makeup.xlsx', engine='openpyxl') # 把月销量里的“万+”统一处理成数值 def parse_sales(s): if isinstance(s, str): s = s.replace('万+', '万').replace('+', '') if '万' in s: return float(s.replace('万', '')) * 10000 return float(s) return s df['月销量_清洗后'] = df['月销量'].apply(parse_sales) df['价格_清洗后'] = pd.to_numeric(df['价格'].astype(str).str.replace('¥', ''), errors='coerce')这一步骤的动机很纯粹:后续所有聚合、排序、画图都依赖数值类型的正确性。如果你的销量字段还是字符串,groupby('品牌')['月销量'].sum()的结果就是一堆字符串拼接,画出来的图离了大谱都发现不了。
2.2 缺失值与异常值的处理策略
缺失值处理上,很多人习惯直接dropna()一把梭,但我建议你谨慎一点。先看缺失比例再进行决策:
- 如果品牌字段缺失——直接删行,品牌是分析主轴,缺失了分析价值不大
- 如果价格字段缺失——看是否能用同品牌同系列商品填充,填充不了就删
- 如果销量字段缺失——保留但标记,或者直接删除,不可拍脑袋填0
异常值这块有个经典案例。某次我看一个同学的数据,某品牌的价格显示为9.9元,点进去一看是“9.9元小样试用装”,这是正装价格的十分之一,如果直接混合进价格带分析,会严重干扰“货单价”的结论。处理办法是加一个辅助列标记SKU类型,或者单独把“小样、中样、试用装”这类关键词过滤出来,再做一轮对照分析。
清洗完毕后,我强烈建议你输出一张data_cleaned.csv,后面所有分析和图表都从这份干净数据出发。不要每次重跑清洗逻辑,这样既能加速调优,也方便答辩时展示“数据从原始态到可用态”的过程。
3. matplotlib可视化的核心拆解:每一张图都是业务问题
到了可视化环节,这是整个项目最有观赏价值的部分。双十一美妆数据能画的图很多,但如果只是一张一张饼图糊上去,评委大概率会问你“这些图的业务结论是什么,能支撑什么决策”。
我建议你把分析问题前置:先有业务问题,再选图表类型。不要先在Excel里看数据长什么样,再决定画什么图。梳理出来的问题大概是这样的:
| 分析维度 | 业务问题 | 图表类型 | 解决的问题 |
|---|---|---|---|
| 品牌格局 | 哪些品牌遥遥领先 | 横向条形图 | 看清谁是头部玩家 |
| 价格带 | 什么价位最容易出爆款 | 柱状图/箱线图 | 判断定价策略 |
| 品类结构 | 护肤彩妆哪个占比大 | 饼图/环形图 | 看清品类集中度 |
| 商品文案 | 爆款标题有哪些高频词 | 词云/条形图 | 提取卖点关键词 |
3.1 品牌销量TOP10:一眼锁定的横向条形图
品牌分析是整个项目里最能出效果的一张图。先按品牌聚合总销量,取前10,用条形图或者水平柱状图展示。
import matplotlib.pyplot as plt import pandas as pd plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False brand_sales = df.groupby('品牌')['月销量_清洗后'].sum().sort_values(ascending=True).tail(10) fig, ax = plt.subplots(figsize=(10, 8)) brand_sales.plot(kind='barh', ax=ax, color='#C71585', edgecolor='white') ax.set_title('双十一美妆品牌销量TOP10', fontsize=15, pad=15) ax.set_xlabel('总销量') ax.set_ylabel('品牌') plt.tight_layout() plt.savefig('output/top10_brands.png', dpi=150, bbox_inches='tight') plt.show()用横向条形图的理由:品牌名这类长文本标签放在y轴,可读性远高于纵向柱状图。颜色上选一个主色调即可,我习惯用粉色系#C71585,呼应美妆主题,但切忌一个柱子一个颜色,那种“彩虹糖”画法在正式汇报里会显得很不专业。
如果你想让这张图更有业务深度,可以拆成两张:一张按总销量排,一张按总销售额排。销量高但销售额低的品牌说明客单价低、走薄利多销路线;销量不高但销售额高的品牌,说明客单价高、是典型的品牌溢价款。两张图放在一起,就能对比出“走量型选手”和“利润型选手”的差异。
3.2 价格带分布:用pd.cut切出业务区间
价格分析是另一个必做项。我习惯把价格切成这样的区间:0-50、50-100、100-200、200-500、500-1000、1000以上,每个区间聚合一下销量总和。
bins = [0, 50, 100, 200, 500, 1000, float('inf')] labels = ['0-50', '50-100', '100-200', '200-500', '500-1000', '1000+'] df['价格带'] = pd.cut(df['价格_清洗后'], bins=bins, labels=labels, right=False) price_group = df.groupby('价格带', observed=False)['月销量_清洗后'].sum() price_group.plot(kind='bar', figsize=(10, 6), color='#FF6EB4', edgecolor='white') plt.title('双十一美妆各价格带销量分布', fontsize=15, pad=15) plt.xlabel('价格带(元)') plt.ylabel('总销量') plt.xticks(rotation=45) plt.tight_layout() plt.savefig('output/price_distribution.png', dpi=150, bbox_inches='tight') plt.show()这里有一个关键的坑:pd.cut切分区间后,默认包含右端点,比如50-100这段实际会包含价格正好等于100的商品。如果不处理,会出现一个商品同时横跨两个区间的情况(严格说不会,因为pandas会自动按左开右闭处理)。建议用right=False让区间变成左闭右开,确保0-50包含50元整,但100元整会落入100-200这个区间。这种细节在答辩时提一嘴,直接加分。
价格带分布出来后,你还能进一步做交叉分析:各价格带里哪个品牌占主导?比如0-50区间可能是国货新锐品牌的阵地,100-200区间可能是国际大牌的中端线的主场。这种交叉分析才是真正“数据分析”该干的事,而不是画完图就收工。
3.3 品类结构与时间趋势:让图表讲故事
品类结构用环形图比饼图更清爽,因为中间留白处可以放总样本数或者核心结论文字。绘制时注意把占比小的品类合并成“其他”,避免图例里挤七八个“1%不到”的小标签。
plotly或者pyecharts做交互图很好看,但如果你的作业要求不强制使用交互可视化,我还是建议用matplotlib。原因很实际:matplotlib的静态图导出PNG后,插入Word或者LaTeX论文里排版不会乱,而交互图在打印版论文里只能截图,反而效果打折。
时间趋势这块要特别说明一下。大多数公开的双十一美妆数据集是截面数据,没有真正的“日期”字段,只有“月销量”。如果强行画时间序列图,其实是把品牌、价格等不同维度的销量对比,包装成了“趋势”。这里我建议的做法是:如果数据里确实有时间字段,比如“双11当天各小时销量”,那做折线图分析高峰时段;如果没有,就别硬画折线图,改为对比图或者雷达图。写数据报告最忌讳为了凑图而画图。
如果手头的数据里有“品牌历史活动期间销量”,倒是可以做增长对比。比如活动前一周、活动当天、活动后一周三个时间点,画分组柱状图,直观展示“双十一当天的爆发效应”,这种图通常会让评委眼前一亮。
4. 400行代码的工程细节与避坑经验
到了这个环节,聊聊代码本身。400行对于数据分析项目来说不算长,但“短而清晰”比“长而晦涩”更考验功夫。
4.1 模块化拆分与代码复用
我见过的一个普遍问题是,很多同学喜欢在Jupyter Notebook里一个格子一个格子地写,代码能跑通但基本不可复用。如果作业要求交付.py格式的源码,我更推荐做成4个文件,每个文件职责单一:
utils.py:只负责数据加载和清洗analysis.py:只负责聚合计算plots.py:只负责图表绘制main.py:负责把全流程串起来
这种结构的好处是:修改图表样式时不用动数据处理逻辑;想加一个新分析维度时,只需要在analysis.py里加一个函数,在plots.py里加一张图,然后main.py里加一行调用。答辩时如果老师问“我想看看某某维度的分析”,你当场改完重新运行,这种临场反应能力本身就是加分项。
此外,定义函数时尽量保持“一个函数只做一件事”。比如load_data()只加载数据,clean_data(df)只处理清洗逻辑,两者不要混在一起。400行的代码,如果每个函数都短小精悍、命名清晰,其可读性比1000行的糊在一起代码高得多。
4.2 matplotlib的两个经典坑:中文字体和图片白边
matplotlib的中文字体问题,是这个项目里最让人头疼的技术点。如果你的系统里没有SimHei或者微软雅黑字体映射,那么所有中文都会变成一个个小方框。解决方案有两种:
import matplotlib.pyplot as plt # 方法1:全局配置(推荐) plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False # 方法2:逐个指定 plt.xlabel('价格带(元)', fontproperties='SimHei')为什么axes.unicode_minus也要设置?因为负号“-”在matplotlib默认字体里是ASCII的,设置中文字体后,坐标轴的负号可能会显示成方块。这个问题很隐蔽,但你一旦设置好全局参数,就不会再遇到。
另一个坑是保存图片时白边过大或截断标签。保存时有三个参数组合是最稳的:
plt.savefig('output/price_distribution.png', dpi=150, bbox_inches='tight')dpi=150:保证印刷级别清晰度,PPT里放大也不糊bbox_inches='tight':自动裁掉多余白边facecolor='white':如果没有设置背景色,保存PNG默认透明背景,贴到Word里可能会出现背景混乱的情况
4.3 数据与代码的路径管理
压缩包解压后,直接双击运行main.py效率很低,如果你是做课程设计,会反复调试代码。建议所有文件路径都用相对路径,且在main.py开头用pathlib统一管理:
from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent DATA_DIR = BASE_DIR / 'data' OUTPUT_DIR = BASE_DIR / 'output' OUTPUT_DIR.mkdir(exist_ok=True)这样无论压缩包被解压到哪里,代码都不会因为绝对路径失效而挂掉。这份代码是给别人“复现”的,如果你的路径写死成C:\Users\xxx\Desktop\...,换一台电脑可能就没法跑了。
5. 答辩与扩展:让项目从“完成”变成“优秀”
如果你的项目是作为大作业交付,答辩环节的表现往往能决定最终分数的上下浮动。结合我过去的经验,分享几个老师最常问的问题和对应的思考角度。
5.1 高频答辩问题速查表
| 常见提问 | 参考回答思路 |
|---|---|
| 为什么选这个数据集? | 数据字段丰富,覆盖品牌/价格/销量/品类,业务场景清晰,适合展示数据分析全流程 |
| 清洗阶段做了什么,为什么做? | 数值字段混入“万+”“¥”符号、缺失值、异常值影响聚合结果,所以必须统一格式并剔除异常 |
| 为什么用柱状图/饼图而不是其他图? | 数据是离散的分类变量,对比大小适合条形图,展示占比结构适合饼图,不用折线图是因为没有连续时间轴 |
| 从图里得出什么业务结论? | 某个价格带销量最高、头部品牌集中度明显、国货在平价价位占比高——每个结论必须和图对上 |
| 这个项目有什么不足? | 样本覆盖面可能有限、没有做销售额和利润的交叉分析、缺少外部数据对标——要敢说不足,但说完要补一句“可以怎么改进” |
第五个问题特别重要。老师问不足,不是为了让你难堪,而是考察你是否对自己的项目有清晰的认知。这时候千万别回答说“没有不足”,也不要说“代码写得不够好”这种空话。更好的回答是:“目前分析停留在描述性统计层面,没有建模预测明年爆款;后续可以引入评论情感分析来补充用户反馈维度。”
5.2 后续扩展的三个方向
如果这门课要求你做的是期末大作业,而且你还想在简历项目栏里凑一笔,这个项目有三个很自然的扩展方向:
- 加交互可视化:把matplotlib换成plotly,输出可交互的HTML文件,体验会有一个质变。但这个扩展会增加大几十行代码,适合有精力的情况
- 加文本挖掘:商品标题和评论往往是文本数据,用
jieba分词做词频分析,或者简单的情感打分,就能让项目从图表展示升级到文本挖掘 - 加业务指标:除了销量和销售额,引入“销售额/销量=客单价”,再做品牌分层(高端/中端/平价),项目就从“描述现状”升级到“辅助定价决策”
每个扩展方向的代码量大概增加50到100行,但分析层次会完全不同。
5.3 实操中的个人心得
最后分享一点个人体会吧。我处理过很多个双十一美妆项目,也见过很多同学拿到数据就开始画图,结果画到第三张图就发现“没什么可分析了”。真正的突破口其实在数据清洗阶段——当你把价格带切好、品牌名称对齐好、数值单位统一好后,分析维度会自然浮现出来。价格带切分完,你自然会想看看不同价位里哪个品牌最强;品牌排名做完,你自然会想看看头部品牌到底在什么价位带发力。数据分析不是先有图再有结论,而是先有问题意识再选图,这个顺序千万别搞反了。
还有一点小建议是:运行一遍代码后,把所有输出图片放在一个文件夹里,肉眼检查一遍有没有字体错乱、坐标轴乱码、标签重叠等小问题。很多项目代码逻辑没问题,但输出了“中文全部变方块”的图,评分会非常尴尬。400行左右的项目,多花10分钟检查输出图表和注释,整体观感能提升一大截。
本文还有配套的精品资源,点击获取