ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

星巴克数据分析案例:从Zip解压到Pandas清洗与可视化实战

星巴克数据分析案例:从Zip解压到Pandas清洗与可视化实战 简介一份基于星巴克门店数据的Python数据分析实战资源内含完整数据集和可运行脚本适合初学者及有经验的分析师系统练习数据清洗、探索性分析、可视化与建模全流程。压缩包共2个文件1个Python程序文件和1个CSV数据表大小仅1.04MB当前已有4355人学习使用。案例覆盖Pandas数据预处理缺失值、异常值、重复值处理、Matplotlib与Seaborn可视化、特征工程以及线性回归、决策树、随机森林和ARIMA、LSTM等模型构建与评估并附有R平方、均方误差等指标解读。代码结构清晰且注释完整通过星巴克门店实际数据可练习绘制热力图、柱状图、箱线图分析不同门店、时间段的销售规律找出影响销售额的关键因素快速积累零售行业实战经验。整个过程可对照代码逐步运行适合作为数据分析入门到进阶的练习项目。1. 拿到“星巴克数据分析案例及数据集.zip”后我先做了什么这个压缩包我其实用了很久每次带新手入门数据分析或者自己需要快速验证一套分析思路时都会把它翻出来当素材。里面是一套星巴克门店维度的业务数据配合分析案例覆盖了从数据清洗、字段处理、可视化到业务解读的完整链路。对想练手的人来说最值钱的地方在于数据足够“脏”字段足够真实做出来的结论又足够贴近商业决策场景。如果你正处在“学完了Python基础语法、看完了几集Pandas教程但不知道拿什么练手”的阶段这套数据很适合你。它不像Kaggle上那些已经帮你清洗好的竞赛数据拿过来跑个模型就完了也不像学校作业数据那么整齐干净。它是那种需要你主动思考“这个字段到底什么意思”“缺失值该怎么处理”“这个分析结论对业务有什么实际帮助”的数据。我在正式分析之前先做了一件事把这个zip解压然后像翻抽屉一样把所有文件列出来挨个看了一遍字段。这一步看起来简单但其实决定了后期分析的顺利程度。因为很多时候项目的成败不在模型多高级而在你对数据本身是否足够了解。2. 这个数据集到底能分析什么字段解读与选题思路2.1 门店维度数据里藏着哪些关键字段把压缩包解压之后里面的核心数据文件通常是一个CSV或者Excel表格。这个数据集的字段设计基本是参照真实的门店运营数据来的常见的字段包括门店名称和门店编号唯一标识这是做主键合并、去重的关键。所属城市和行政区对应到城市一级可以做区域分布分析也能和城市的GDP、人口数据做关联。经纬度这个字段特别关键有了它你可以做门店地理分布的可视化比如用散点图画出门店在全国的分布热力甚至可以结合城市边界做密度分析。营业状态和营业时间判断门店是否正常运营以及营业时长分布。饮品类别和价格如果数据集中包含这部分就可以做价格带分析比如星巴克在不同城市、不同商圈的定价策略有什么差异。我拿到字段后第一件事就是先把字段的中文含义、数据类型、缺失情况列了一张表。这样做的好处是后面写代码时你不会反复回去看数据字典而且对数据质量能有一个整体把控。2.2 围绕这份数据可以做哪些高价值选题如果你不知道拿这份数据做什么我给你几个实际操作过且效果不错的选题门店地理分布特征分析用经纬度做全国门店分布的可视化分析哪些省份、哪些城市门店密度最高。结合城市等级一线、新一线、二线来看能得出星巴克门店选址的城市层级策略。城市门店密度与经济发展水平的关系把门店数量排序再和城市GDP、人均可支配收入做初步对比分析星巴克在哪些城市属于“高密度低收入”或“低密度高收入”区域这对理解品牌扩张逻辑很有帮助。门店营业时长与商圈类型的交叉分析营业时间长短往往反映门店所处商圈的类型商场店、写字楼店、社区店的营业时段差异很大。如果数据中有位置类型字段可以做交叉统计。这些选题的优点是不需要太复杂的模型用Pandas做分组聚合、再配几组可视化图表就能出结果。但它们的业务含义非常丰富面试时讲出来不会让人觉得你只是在“跑代码”。3. 从解压到出结果核心实操流程全记录3.1 先解决一个基础问题zip文件怎么处理既然这套数据是以zip压缩包形式提供的你先得把它解开。网上关于zip的解压工具有很多但我不太推荐额外安装第三方软件因为Python标准库里的zipfile模块就够用了。如果你和我一样习惯在命令行操作解压其实只需要几行代码import zipfile with zipfile.ZipFile(星巴克数据分析案例及数据集.zip, r) as z: z.extractall(./starbucks_data) print(z.namelist())解压之后先用namelist()打印一下压缩包里的文件清单。这一步很重要可以让你确认里面的数据结构是单文件还是多文件是CSV还是Excel还是说附带了说明文档和SQL脚本。我见过不少人拿到压缩包后直接双击、拖拽、强行解压导致中文文件名乱码后面光处理路径就折腾了半天其实用代码解压更稳。特别注意如果压缩包是带密码的直接用extractall会报错。此时需要给ZipFile传入pwd参数比如zipfile.ZipFile(xxx.zip, r, pwdbpassword)。如果是你自己加密的文件别问我密码是多少这个我帮不了你。3.2 用Pandas把数据读取进来完成第一轮清洗数据解压出来后直接用pandas.read_csv()读取或者如果文件是Excel格式就用pandas.read_excel()。不过读取只是开始真正的重头戏是清洗。第一步是处理缺失值。门店名称、城市这类关键字段如果缺失对应的行要么删除、要么补全取决于缺失比例。我当时的做法是先看缺失比例低于5%的字段直接删除缺失行高于5%的字段判断是不是有规律性缺失。比如有些门店的营业时间缺失可能是因为该店刚开业还没有统计数据这种情况我会统一填充为“未知”。第二步是去重。理论上门店编号是唯一的但如果数据合并过多次可能会出现同一个门店编号对应多条记录。我的习惯是先按门店编号排序再对重复行做一次确认确认后保留最新一条记录。第三步是字段类型纠正。经纬度如果被读成字符串后续计算距离、画图都会出问题。我一般会在读取时直接指定dtype或者读取后用pd.to_numeric()强制转换。import pandas as pd df pd.read_csv(./starbucks_data/starbucks_store_locations.csv) df[latitude] pd.to_numeric(df[latitude], errorscoerce) df[longitude] pd.to_numeric(df[longitude], errorscoerce)这里有两点心得。第一errorscoerce会让非法值变成NaN方便后续统一处理非常实用。第二清洗完数据后一定要另外存一份清洗后的文件千万别直接在原数据上改动。因为后面你很可能做错一步还想回到原始状态重新来有备份就不慌。3.3 第一个实战分析全国门店地理分布可视化清洗完成后我做的第一个分析是门店地理分布。这一步是热身的主要目的是验证数据质量和全局观感。我用的是plotly.express的散点地图因为它在Jupyter里交互体验好、不用额外申请地图服务密钥特别适合快速看分布。核心代码其实很简洁import plotly.express as px fig px.scatter_mapbox( df, latlatitude, lonlongitude, hover_namestore_name, colorcity, zoom3, height600, ) fig.update_layout(mapbox_styleopen-street-map) fig.show()跑出来的图很直观东部沿海地区门店密度明显高于中西部京津冀、长三角、珠三角是三大核心聚集区成都、重庆、武汉等新一线城市也有比较密集的布局。这和星巴克中国区的城市扩张策略是对得上的。但光是“画出一张图”是不够的。作为数据分析师你要从图里读出业务含义。我当时得出的结论是星巴克的门店分布呈现出典型的“以经济发达城市为核心向外辐射”的特征。这也引出了一个后续可以深挖的方向——门店密度到底和城市的哪些经济指标关联最强。3.4 第二个实战分析城市门店数量Top20排名做完地图分布我又做了一张门店数量Top20城市的柱状图。这一步用分组聚合就能完成city_counts df.groupby(city)[store_name].count().sort_values(ascendingFalse).head(20) import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False city_counts.plot(kindbar, figsize(12, 6), color#00704A) plt.title(星巴克门店数量Top20城市) plt.xlabel(城市) plt.ylabel(门店数) plt.show()这里有个特别容易踩的坑Matplotlib默认不显示中文必须设置中文字体。我一开始没设置时图上的城市名全是方块乱码看着特别崩溃。后来我统一用plt.rcParams[font.sans-serif] [SimHei]解决掉这个问题。Top20的结果里上海、北京的门店数遥遥领先这和它们的城市体量、消费能力是匹配的。但值得关注的是一些新一线城市的门店数已经追赶上来了这说明星巴克这几年在新一线城市的布局力度明显加强。这种结论如果用纯文字描述撑死两三行但一配上图表整个分析的说服力就出来了。3.5 第三个实战分析营业时长分组统计第三个分析我选了营业时长这个容易被忽略的字段。先用pd.to_datetime()把营业开始和结束时间转成标准时间格式然后计算营业时长df[open_time] pd.to_datetime(df[open_time], format%H:%M, errorscoerce) df[close_time] pd.to_datetime(df[close_time], format%H:%M, errorscoerce) df[duration_hours] (df[close_time] - df[open_time]).dt.seconds / 3600这里有个小知识点dt.seconds拿到的是“从当天零点开始算的秒数”如果你的关门时间跨过午夜比如营业到次日凌晨2点直接相减会得到负值。我的处理办法是加个判断如果close_time open_time就说明跨天了加24小时再算。分组统计的结果显示大部分门店的营业时长为10到12小时少数位于机场、枢纽位置的门店营业时长超过14小时。这符合常理枢纽型门店要匹配交通班次时间营业时长自然拉长。这个分析本身不算复杂但特别适合在面试时讲因为它展示了你对业务场景的思考而不只是机械地算数。4. 常见问题与避坑实录我踩过的那些坑4.1 zip解压后中文文件名乱码这个问题太常见了。Windows上用系统自带的解压工具解压包含中文文件名的zip包有时会乱码。原因是压缩包内的文件名编码可能不是GBK而Windows解压工具默认按GBK解码。解决方式还是回到Python。读取时指定元数据编码或者解压后手动重命名。我更喜欢用zipfile配合shutil把文件逐个提取出来遇到乱码文件就重命名import zipfile, shutil with zipfile.ZipFile(星巴克数据分析案例及数据集.zip, r) as z: for info in z.infolist(): try: filename info.filename.encode(cp437).decode(gbk) except UnicodeDecodeError: filename info.filename with z.open(info) as src, open(filename, wb) as dst: shutil.copyfileobj(src, dst)这段代码的核心思路是zipfile 默认用 cp437 编码去解析文件名我手动把它转成 gbk 再保存文件名就正常了。如果是Mac上解压的编码规则可能相反需要灵活调整。4.2 数据读取时出现编码错误CSV文件的编码问题也是高频坑。有些CSV文件表面看是UTF-8实际上带着BOM头pandas读取后第一列列名会带一个\ufeff前缀排查问题时很难发现。解决办法是读取时加一个encodingutf-8-sig顺便就把BOM去掉了。如果数据是GBK编码读取时就要用encodinggbk。我的建议是准备一个通用函数自动尝试UTF-8、GBK、GB2312、Latin-1哪个不报错就用哪个能省不少事。4.3 重复数据怎么去重才算干净很多人拿到数据就drop_duplicates()一把梭这样很容易误删有效数据。我自己的经验是先看重复发生在哪些字段上如果整个记录完全重复删除没毛病如果只是门店编号重复但其他字段有差异那可能是一店多址或者数据更新产生的版本差异不能直接删。我通常的做法是按门店编号分组查看每组记录数再逐组判断保留哪条。虽然效率低一点但数据质量有保障。分析这种事宁可前期多花点时间也比得出错误结论强。4.4 表格数据字段类型不匹配门店编号有时候会被Excel自动转成“科学计数法”比如1.2E08这种读到Pandas里一堆乱码。我的处理办法是读取时直接用dtype参数指定字段类型把它强制读成字符串。df pd.read_csv(./starbucks_data/starbucks_store_locations.csv, dtype{store_number: str})这种细节看起来很小但实际处理数据时特别折磨人。尤其是门店编号这类字段你根本不会第一时间想到是被Excel改了格式等分析到后面才发现ID对不上回头排查的成本极高。4.5 常用问题速查表问题现象可能原因解决方案中文文件名乱码zip内部编码与系统不一致用Python zipfile配合重命名提取CSV读取后列名带\ufeff文件保存时带BOM头pandas读取时指定utf-8-sig日期时间字段无法计算时间格式不规范pd.to_datetime强制转换errorscoerce经纬度变成字符串原始数据混有异常值pd.to_numeric转换errorscoerce跨日营业时间计算错误结束时间小于开始时间判断后加24小时再计算Matplotlib图中文乱码缺少中文字体配置设置plt.rcParams中的sans-serif字体5. 如何把这个案例做成一个拿得出手的项目而不是“交作业”很多初学者做数据分析项目最大的问题是“做完就扔”。数据导出来、图表画完、结论写完然后就没有然后了。这样的项目放到简历上面试官看完只会觉得哦你跑了一遍pandas的入门教程。我的建议是拿到这套星巴克数据后至少做三件额外的事让它变成一个真正能打的项目。第一件把分析整理成一份结构完整的报告。不要只扔一堆代码要写清楚“背景—数据说明—分析方法—关键发现—业务建议”五个部分。尤其是业务建议比如“门店扩张可优先考虑GDP增速快、目前门店密度不高的二线城市”这种话才叫分析结论。对了建议用Markdown或Jupyter Notebook整理既能展示代码又能展示文字。第二件加一个简单的预测模型。比如根据城市人口、GDP、消费指数等外部数据预测某个城市应该开多少家门店比较合理。即使数据集中没有这些外部字段你也可以尝试通过爬虫或公开统计年鉴去补充。加预测模型这一步整个项目的技术含量会上一个档次从“描述性分析”变成“决策性分析”。第三件做一张数据看板。用Tableau或者Power BI把门店分布、数量排名、营业时长等核心指标汇总到一张仪表盘上。不需要特别复杂但要把分析结果以可视化方式固化下来后期汇报时直接截图就能用。这个步骤对我来说非常管用因为刚开始我不重视数据看板总觉得能用代码画图就行但真到了汇报场景一张清晰的看板比十张散落的图有力得多。如果你时间充裕还可以把同样的分析流程迁移到其他品牌数据上比如麦当劳、肯德基、瑞幸的门店数据。换一个数据集重新走一遍流程你会发现很多当时没理解透的细节突然就通了。这也是我反复用这套数据的原因——数据简单但不简陋足够撑起一个完整的项目却又不至于让新手无从下手。最后再分享一个我个人的习惯做数据分析项目不要追求一步到位。第一次能跑通已经成功了大半跑通之后再去优化每一步比如补缺失值、加图表、做预测模型一步步迭代。分析数据的核心能力就是在这样一次次迭代里练出来的。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进