Python数据分析实战:网易云歌单可视化作业全流程
发布时间:2026/10/1 23:48:07来源:尧图网络
简介这份资源是面向高校学生与 Python 数据分析初学者的结课项目实战包以网易云音乐歌单为分析对象解决从数据获取到可视化呈现的完整流程问题适合作为课程作业参考或数据分析入门练手案例。压缩包共 39 个文件约 10.53MB包含 12 个 py 源码、11 个 pyc 编译文件、7 张 png 图表、3 个 csv 数据文件以及 md 说明、ttf 字体、pdf 报告等覆盖代码、数据与成果展示三类内容。项目借助 numpy、pandas、matplotlib、requests、squarify、jieba、wordcloud、bs4 等第三方模块完成歌单数据的抓取与清洗并输出评论、收藏、播放、贡献、分布等数量图及词云最后给出歌单优化建议。已有 3342 人学习读者可据此理解数据分析项目的目录组织与模块分工掌握爬虫、分词、词云与统计图表的组合用法并借鉴其分析思路与结论表达方式。1. 从一份网易云歌单出发这套 Python 数据分析作业到底能跑出什么你可能遇到过这种场景课程设计要交一份数据分析作业手头有 Python 环境但不知道拿什么数据练手。这份「基于 Python 数据可视化的网易云音乐歌单分析系统」就是冲着这个需求来的——它把歌单数据抓取、清洗、统计、可视化串成一条完整链路适合正在学 python 数据分析、需要交编程作业、又想顺便把 pandas 和 matplotlib 摸熟的人。它不教你从零写爬虫框架而是给你一套能直接跑通的分析流程读数据、算指标、出图表、拼报告。歌单本身是个很好的切入点字段直观歌名、歌手、时长、热度数据量适中跑起来不卡机器结果又能一眼看懂。如果你正卡在「有工具没场景」的阶段这份资源能让你把 python 数据分析与可视化 的课本知识真正落到一次可交付的作业上。2. 数据从哪来、字段怎么定歌单分析的输入层设计2.1 为什么选歌单而不是评论或播放记录做数据分析作业第一步不是写代码是决定数据源。网易云音乐可拿到的公开数据里歌单是性价比最高的评论数据字段少、情感分析门槛高播放记录涉及个人隐私拿不到而歌单天然带结构化字段一首歌对应一行歌手、时长、热度都是现成的数值或类别清洗成本低。常见做法是先用 requests 拉取歌单详情接口把 JSON 落成 CSV后续所有分析都基于这份本地文件避免每次跑脚本都重新请求。这样做的另一个好处是作业可复现——老师拿到你的代码和 CSV不联网也能跑出同样的图。歌单数据的核心字段一般包括歌曲名、歌手、专辑、时长毫秒、热度值、评论数。其中时长和热度是数值型直接进统计歌手和专辑是类别型适合做 Top N 排行。选这套字段的理由是它们能撑起四类基础图表柱状图看歌手分布、饼图看时长区间占比、散点图看热度与评论数的关系、折线图看歌单内歌曲热度走势。字段不用多够画出四张图、讲清一个结论作业就立住了。2.2 用 pandas 读数据并做第一轮体检拿到 CSV 之后别急着画图先做数据体检。这一步能帮你提前发现空值、类型错误和重复行省得后面图表出来是歪的。import pandas as pd # 读取歌单数据指定编码防止中文乱码 df pd.read_csv(playlist.csv, encodingutf-8-sig) # 第一轮体检看形状、类型、空值 print(数据形状:, df.shape) print(字段类型:\n, df.dtypes) print(空值统计:\n, df.isnull().sum()) # 时长从毫秒转成秒方便后续分区间 df[duration_s] df[duration] / 1000 # 去掉歌名重复的行保留第一条 df df.drop_duplicates(subset[song_name], keepfirst) print(去重后形状:, df.shape)这段代码的逻辑是先确认数据规模再检查每个字段的类型是否符合预期比如热度应该是 int 或 float如果读成 object 说明有脏字符然后统计空值分布。encodingutf-8-sig是为了处理带 BOM 的中文 CSV不加这个参数经常出现第一列字段名带乱码。时长除以 1000 是因为原始接口返回的是毫秒人看秒更直观。去重按歌名做因为同一首歌可能在歌单里出现多次重复会拉高排行统计的偏差。参数上唯一需要按你实际数据调整的是subset如果歌名有重名但歌手不同可以改成subset[song_name, artist]。跑完这一步你应该得到一份行数略少于原始数据、字段类型干净、没有关键空值的 DataFrame这就是后续所有分析的底座。3. 统计与可视化把歌单数据变成四张能交作业的图3.1 歌手排行与时长分布的统计口径统计部分最容易翻车的地方不是代码是口径。比如「歌手排行」到底按歌曲数量排还是按总热度排结果完全不同。我一般会两个都算作业里分别说明显得分析有层次。# 按歌曲数量统计歌手排行 artist_count df[artist].value_counts().head(10) # 按总热度统计歌手排行 artist_heat df.groupby(artist)[popularity].sum().sort_values(ascendingFalse).head(10) # 时长分区间短于3分钟、3到5分钟、超过5分钟 bins [0, 180, 300, float(inf)] labels [短歌(3min), 标准(3-5min), 长歌(5min)] df[duration_bin] pd.cut(df[duration_s], binsbins, labelslabels) duration_dist df[duration_bin].value_counts()value_counts()默认按频次降序取 head(10) 就是 Top10 歌手。groupby加sum是按热度聚合适合看谁的作品整体更受欢迎。pd.cut做分箱时bins的边界要覆盖数据最小值到最大值float(inf)表示不设上限避免有超长歌曲被漏掉。labels 用中文是为了图表直接可读不用再映射。这三个统计结果分别对应柱状图、柱状图和饼图数据量小跑起来秒出。3.2 用 matplotlib 出图并处理中文显示可视化环节最经典的坑是中文变方块。matplotlib 默认字体不含中文必须手动指定。下面这段是出图模板改数据源就能复用。import matplotlib.pyplot as plt # 指定中文字体Windows 用 SimHeiMac 用 Arial Unicode MS plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False # 解决负号显示为方块 fig, axes plt.subplots(2, 2, figsize(12, 10)) # 图1歌手歌曲数量 Top10 artist_count.plot(kindbar, axaxes[0, 0], color#4C72B0) axes[0, 0].set_title(歌手歌曲数量 Top10) axes[0, 0].set_ylabel(歌曲数) # 图2时长区间分布 duration_dist.plot(kindpie, axaxes[0, 1], autopct%1.1f%%) axes[0, 1].set_title(歌曲时长分布) axes[0, 1].set_ylabel() # 图3热度与评论数散点 axes[1, 0].scatter(df[popularity], df[comment_count], alpha0.5) axes[1, 0].set_xlabel(热度) axes[1, 0].set_ylabel(评论数) axes[1, 0].set_title(热度与评论数关系) # 图4歌单内热度走势 axes[1, 1].plot(df[popularity].values, color#C44E52) axes[1, 1].set_title(歌单热度走势) axes[1, 1].set_xlabel(歌曲序号) axes[1, 1].set_ylabel(热度) plt.tight_layout() plt.savefig(playlist_analysis.png, dpi150) plt.show()font.sans-serif设成 SimHei 是 Windows 下的通用做法Mac 用户改成Arial Unicode MSLinux 服务器上如果没有中文字体可以提前装一个思源黑体再指定字体名。axes.unicode_minus False这行不加负号会显示成方块虽然歌单数据一般没负数但养成习惯没坏处。subplots(2, 2)一次排四张图tight_layout()自动调整间距防止标题重叠dpi150保证导出图片够清晰交作业打印也不糊。散点图加alpha0.5是为了重叠点能看出密度不然点全糊成一团。3.3 把图表拼成一份能交的作业报告图出来只是半成品作业要的是有结论的报告。常见做法是用 matplotlib 的savefig导出图片再在 Markdown 或 Word 里写文字说明。每张图配三句话这张图看什么、数据说明了什么、和歌单主题有什么关系。比如时长分布饼图如果显示标准时长占 70%就可以写「该歌单以 3 到 5 分钟的主流流行歌曲为主符合大众听歌习惯」。这一步不需要额外代码但决定了作业是「跑了个脚本」还是「做了次分析」。如果想让报告更自动可以用df.describe()导出统计摘要把均值、中位数、最大最小值贴进报告数据支撑更硬。4. 避坑与排查跑这套分析时最容易翻车的五个地方4.1 中文乱码图表方块和 CSV 读歪现象是图表标题全是方块或者读 CSV 时第一列字段名带\ufeff。原因是 matplotlib 没指定中文字体以及 CSV 带 BOM 头。解决办法是出图前设plt.rcParams[font.sans-serif]读文件用encodingutf-8-sig。如果换了环境字体名不对用matplotlib.font_manager查一下系统里有哪些中文字体再填。4.2 字段类型错误热度被读成字符串现象是df[popularity].sum()报错或结果变成字符串拼接。原因是 CSV 里热度列混了非数字字符pandas 推断成 object。解决办法是读数据时加dtype{popularity: float}强制指定或者读完后用pd.to_numeric(df[popularity], errorscoerce)转换coerce会把无法转换的变成 NaN再决定是删还是填。4.3 分箱边界漏数据最长歌曲没进任何区间现象是value_counts()的总数小于 DataFrame 行数。原因是pd.cut的 bins 上限设小了超过上限的值变成 NaN。解决办法是把最后一个边界设成float(inf)或者先用df[duration_s].max()看一眼最大值再定边界。这个坑很隐蔽因为不报错只是数据悄悄少了。4.4 去重口径过宽不同歌手的同名歌被误删现象是去重后行数掉得比预期多。原因是drop_duplicates只按歌名去重把不同歌手的同名歌也删了。解决办法是subset加上歌手字段subset[song_name, artist]。如果连翻唱版本都要保留就再加专辑字段口径越细保留越多。4.5 图片保存空白show 和 savefig 顺序反了现象是savefig出来的图片是空白。原因是在某些后端下plt.show()会清空画布之后再保存就没了。解决办法是把savefig放在show之前或者干脆不调show直接保存。这个坑在 Jupyter 里不明显换成脚本跑就暴露了。5. 进阶玩法让这份作业从及格变成有记忆点基础四张图能交差但想让作业被记住得加一点别人没做的。我一般会从两个方向切一是加一层「时间维度」如果歌单数据里能拿到歌曲发行年份就按年份做折线图看这个歌单是怀旧型还是追新型二是加一层「文本维度」把歌手名字做词云或者把歌名里的高频词提出来用 jieba 分词后统计。这两个方向都不难但能让报告从「统计了数据」变成「发现了点什么」。词云的做法是先装wordcloud和jieba把歌名拼成一个长字符串分词后过滤掉单字和停用词再生成词云图。参数上font_path必须指定中文字体路径否则又是方块max_words控制显示词数一般 50 到 100 够用background_color设成白色方便打印。年份折线图更简单groupby年份后count再plot就行但前提是数据里有年份字段没有的话这一步跳过别硬编。验证方法上我习惯跑完所有图后回头对一遍总数每张图的数据加起来应该等于去重后的行数对不上就说明有数据在某个环节被漏掉或重复计算。这个习惯是从一次作业翻车里养成的——当时饼图加起来只有 85%查了半天发现是分箱边界漏了长尾数据。从那以后我每次出完图都强制走一遍总数核对宁可多花五分钟也不想到答辩时被问住。如果想让代码更工程化可以把读数据、清洗、统计、出图拆成四个函数主流程只负责调用。这样改数据源时只动读数据那一步其他不用碰。函数命名用动词开头比如load_playlist、clean_data、compute_stats、plot_charts别人接手一眼能看懂。这套结构不复杂但能体现你不只是会跑脚本还知道怎么组织代码作业评分上是个加分项。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网