Python分析Spotify听歌数据:从API获取到高级可视化
1. 项目概述从数据角度重新认识你的音乐品味作为一个长期使用Spotify的音乐爱好者我发现自己经常在年底收到平台的年度回顾报告时感到惊喜——原来我今年听了这么多遍这首歌。这种数据驱动的自我发现体验让我萌生了一个想法为什么不自己动手分析这些数据呢于是就有了这个用Python解析个人Spotify听歌数据的项目。这个项目的核心价值在于它让你摆脱平台预设的分析框架完全按照个人兴趣来探索自己的音乐行为模式。比如你可以发现每周不同时段的音乐偏好变化特定情绪状态下的歌曲选择规律长期音乐品味的演变轨迹甚至预测下一首可能会喜欢的歌曲提示Spotify官方API提供了6个月内的详细收听记录但通过数据请求可以获取完整的收听历史需要特别申请。2. 环境准备与数据获取2.1 创建Spotify开发者应用首先需要在 Spotify开发者平台 创建一个应用来获取API凭证登录后点击Create an App填写应用名称和描述可以随意填写记录下生成的Client ID和Client Secret在设置中添加回调URL本地开发可以用http://localhost:8080# 配置示例 SPOTIFY_CLIENT_ID your_client_id SPOTIFY_CLIENT_SECRET your_client_secret REDIRECT_URI http://localhost:80802.2 获取个人收听数据Spotify提供两种数据获取方式通过API获取近期数据最近6个月需要用户授权可以实时获取包含播放次数、时间戳等详细信息请求完整数据副本可能需要30天通过 隐私设置页面 申请包含所有历史收听记录数据以JSON格式提供# 使用spotipy库进行认证 import spotipy from spotipy.oauth2 import SpotifyOAuth scope user-read-recently-played user-top-read sp spotipy.Spotify(auth_managerSpotifyOAuth( client_idSPOTIFY_CLIENT_ID, client_secretSPOTIFY_CLIENT_SECRET, redirect_uriREDIRECT_URI, scopescope))3. 数据分析核心模块实现3.1 基础数据清洗与转换原始数据通常需要经过以下处理def clean_spotify_data(raw_data): # 转换时间戳 raw_data[played_at] pd.to_datetime(raw_data[played_at]) # 提取音频特征 track_ids raw_data[track_id].tolist() audio_features [] for i in range(0, len(track_ids), 50): batch track_ids[i:i50] audio_features.extend(sp.audio_features(batch)) # 合并数据 features_df pd.DataFrame(audio_features) merged_df pd.merge(raw_data, features_df, left_ontrack_id, right_onid) # 添加衍生特征 merged_df[hour_of_day] merged_df[played_at].dt.hour merged_df[day_of_week] merged_df[played_at].dt.dayofweek merged_df[is_weekend] merged_df[day_of_week].isin([5,6]).astype(int) return merged_df3.2 音乐特征分析Spotify为每首歌曲提供了丰富的音频特征特征说明分析价值danceability舞蹈性识别运动时的音乐偏好energy能量感分析不同时段的能量需求valence愉悦度情绪状态推断tempo速度(BPM)活动强度关联分析speechiness语言含量学习/工作时的偏好acousticness原声程度品味演变分析def analyze_audio_features(df): # 时段特征分析 time_features df.groupby(hour_of_day)[ [danceability, energy, valence] ].mean().reset_index() # 周特征分析 weekly_pattern df.groupby(day_of_week)[ tempo ].agg([mean, count]).reset_index() # 情绪聚类 from sklearn.cluster import KMeans kmeans KMeans(n_clusters3) df[mood_cluster] kmeans.fit_predict(df[[valence, energy]]) return { time_features: time_features, weekly_pattern: weekly_pattern, mood_clusters: kmeans.cluster_centers_ }3.3 收听行为可视化使用Plotly创建交互式可视化import plotly.express as px def create_heatmap(df): fig px.density_heatmap( df, xhour_of_day, yday_of_week, zdanceability, histfuncavg, title一周内舞蹈性偏好变化 ) fig.update_layout( yaxis_title星期几, xaxis_title小时, yaxisdict(tickvalslist(range(7)), ticktext[周一,周二,周三,周四,周五,周六,周日]) ) return fig def create_mood_scatter(df): fig px.scatter( df, xvalence, yenergy, colormood_cluster, hover_data[track_name], title歌曲情绪分布 ) return fig4. 高级分析技巧4.1 音乐品味演变分析通过时间序列分析观察音乐品味的变化def analyze_temporal_trends(df): # 按月聚合 monthly df.set_index(played_at).resample(M)[ [danceability, energy, valence] ].mean() # 滚动平均平滑 smooth monthly.rolling(window3).mean() # 绘制趋势线 fig px.line(smooth, title音乐特征月度变化趋势) return fig4.2 艺人网络关系图分析你经常一起听的艺人之间的关系import networkx as nx def create_artist_network(df): # 创建共现矩阵 artist_pairs df.groupby(played_at)[artist_name].unique().apply( lambda x: list(itertools.combinations(x, 2)) if len(x)1 else [] ).explode().dropna() # 构建图 G nx.Graph() for pair in artist_pairs: if G.has_edge(*pair): G.edges[pair][weight] 1 else: G.add_edge(*pair, weight1) # 可视化 pos nx.spring_layout(G) nx.draw(G, pos, with_labelsTrue, edge_color[d[weight] for _,_,d in G.edges(dataTrue)])4.3 播放预测模型基于历史数据预测未来可能喜欢的歌曲from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split def build_recommendation_model(df): # 标记常听歌曲 play_counts df[track_id].value_counts() df[is_frequent] df[track_id].apply( lambda x: 1 if play_counts[x] play_counts.quantile(0.75) else 0) # 准备特征 features [danceability, energy, valence, tempo, hour_of_day, day_of_week] X df[features] y df[is_frequent] # 训练模型 X_train, X_test, y_train, y_test train_test_split(X, y) model RandomForestClassifier() model.fit(X_train, y_train) return model5. 实战经验与避坑指南5.1 数据获取常见问题API速率限制Spotify API每分钟限制100次请求批量获取音频特征时需分块处理建议50首/批添加适当的sleep间隔0.5-1秒历史数据不完整官方API只提供最近6个月数据完整数据需要单独申请处理时间可能长达30天建议定期备份自己的收听数据认证令牌过期访问令牌1小时后失效使用刷新令牌自动获取新令牌实现令牌持久化存储# 令牌刷新示例 def get_refreshed_token(): auth_manager SpotifyOAuth( client_idSPOTIFY_CLIENT_ID, client_secretSPOTIFY_CLIENT_SECRET, redirect_uriREDIRECT_URI, scopescope) if not auth_manager.validate_token(auth_manager.get_cached_token()): auth_manager.refresh_access_token(auth_manager.get_cached_token()[refresh_token]) return auth_manager.get_access_token()5.2 分析技巧进阶时段分析的黄金分割不要简单按小时分析尝试划分早晨通勤(7-9)工作时间(9-12, 13-17)晚间放松(18-22)深夜时段(23-3)情绪四象限法将valence和energy组合为高能快乐(右上)高能愤怒(右下)低能悲伤(左下)低能平静(左上)艺人影响力指数def calculate_artist_impact(df): play_counts df[artist_name].value_counts() recency (pd.Timestamp.now() - df.groupby(artist_name)[played_at].max()).dt.days impact play_counts / (recency 1) # 1避免除零 return impact.sort_values(ascendingFalse)5.3 可视化优化技巧颜色主题选择情绪分析使用红色(愤怒)-黄色(快乐)-蓝色(悲伤)渐变时段分析使用日出到日落的颜色渐变艺人网络使用Spotify品牌绿作为主色交互式提示设计fig.update_traces( hovertemplateb%{customdata[0]}/bbr 艺人: %{customdata[1]}br 播放时间: %{customdata[2]}br 舞蹈性: %{x:.2f}br 能量: %{y:.2f}extra/extra )动态时间轴fig px.scatter( df, xvalence, yenergy, animation_framedf[played_at].dt.strftime(%Y-%m), range_x[0,1], range_y[0,1] )6. 项目扩展方向6.1 实时收听仪表板使用Dash构建实时监控面板import dash from dash import dcc, html app dash.Dash(__name__) app.layout html.Div([ dcc.Graph(idmood-scatter), dcc.Interval( idinterval-component, interval60*1000, # 1分钟刷新 n_intervals0 ) ]) app.callback( Output(mood-scatter, figure), Input(interval-component, n_intervals) ) def update_graph(n): recent_tracks get_recently_played() return create_mood_scatter(recent_tracks)6.2 自动播放列表生成基于分析结果创建智能播放列表def create_mood_playlist(df, moodcalm): mood_filters { calm: (df[energy] 0.4) (df[valence] 0.6), energetic: (df[energy] 0.7) (df[danceability] 0.7), focus: (df[speechiness] 0.1) (df[tempo].between(50, 70)) } track_uris df[mood_filters[mood]][track_uri].tolist() playlist sp.user_playlist_create( user_id, f我的{mood}歌单 - {datetime.now().strftime(%Y-%m-%d)}, publicFalse) sp.playlist_add_items(playlist[id], track_uris[:50])6.3 跨平台数据整合结合Last.fm等其他平台数据def merge_multiple_sources(spotify_df, lastfm_df): # 统一时间格式 lastfm_df[timestamp] pd.to_datetime(lastfm_df[timestamp], units) # 合并数据集 merged pd.concat([ spotify_df[[track_name, artist_name, played_at]], lastfm_df[[track_name, artist_name, timestamp]].rename( columns{timestamp: played_at}) ]) # 去重并排序 return merged.drop_duplicates().sort_values(played_at)在完成这个项目的过程中我发现最有意思的洞察是工作日和周末的音乐选择差异远比想象中大——周一到周五我倾向于听更多器乐和低歌词含量的音乐可能是为了专注工作而周末则明显偏好节奏感强的流行音乐。这种模式在数据可视化中呈现出惊人的规律性让我开始有意识地调整不同场景下的音乐选择策略。

相关新闻

数据仓库实施六步法:从需求分析到可信报表落地

数据仓库实施六步法:从需求分析到可信报表落地

简介:本资源是一份面向企业数据工程师、BI开发人员及数字化转型管理者的数据仓库实施方法论实战指南,系统解决从业务需求分析到报表落地的全流程技术落地难题。内容覆盖需求调研要点、ODS双模式设计(缓冲区与信息视图区)、分层架构…

2026/10/15 9:58:54 阅读更多 →
AI Agent沙箱实战:从线上事故到安全隔离的工程指南

AI Agent沙箱实战:从线上事故到安全隔离的工程指南

1. 从一次线上事故说起:为什么你的Agent需要一个"笼子"去年冬天,我负责的一个自动化任务系统在凌晨三点突然开始疯狂调用外部接口,短短二十分钟内触发了上千次请求,直接把下游服务打挂了。事后复盘发现,问题…

2026/10/15 9:58:54 阅读更多 →
PDM、uv等新工具如何重塑Python包管理?

PDM、uv等新工具如何重塑Python包管理?

包的管理体系在过去这一段时间里发展得非常迅速, 几乎到了爆炸的程度, 大家可以把过去十年当成一个观察期。在最初的阶段, 开发者主要依靠的是 pip 这个工具配合 .txt 这样的文件来进行操作, 而现在出现了 PDM、uv 等现代化的工具, 虽然种类很多, 但往往会让开发人员在选择的时…

2026/10/15 9:58:54 阅读更多 →

最新新闻

学Simulink——储能变流器(PCS)中 PWM 整流器的恒流充放电(CC Charge / CC Discharge)仿真

学Simulink——储能变流器(PCS)中 PWM 整流器的恒流充放电(CC Charge / CC Discharge)仿真

目录 手把手教你学Simulink——储能变流器(PCS)中 PWM 整流器的恒流充放电(CC Charge / CC Discharge)仿真 一、为什么储能 PCS 要做 恒流(CC)充放电双向 PWM 整流器 二、PCS 双向控制与 CC 模式原理** 2.1 功率平衡估算(用于 idref​折算) 2.2 模式定义 三、关键…

2026/10/15 10:38:32 阅读更多 →
TaoToken 视角下的示波器使用:measure/acquire/storage/cursor 四步实测

TaoToken 视角下的示波器使用:measure/acquire/storage/cursor 四步实测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 10:38:32 阅读更多 →
学Simulink——三相 PWM 整流器在船舶岸电系统(Shore-to-Ship Power, Cold Ironing)中的并网控制仿真

学Simulink——三相 PWM 整流器在船舶岸电系统(Shore-to-Ship Power, Cold Ironing)中的并网控制仿真

目录 手把手教你学Simulink——三相 PWM 整流器在船舶岸电系统(Shore-to-Ship Power, Cold Ironing)中的并网控制仿真 一、为什么船舶岸电系统要用 三相 PWM 整流器/并网变流器 二、岸电系统典型参数(教学模型)** 三、Simulink 建模(手把手)** 3.1 Step 1️⃣ —— 港…

2026/10/15 10:38:32 阅读更多 →
PP-HumanSeg Lite + NCNN C++ 部署实战:精准版本对齐与边缘落地

PP-HumanSeg Lite + NCNN C++ 部署实战:精准版本对齐与边缘落地

简介:本资源是一套面向嵌入式与移动端开发者的轻量级人像分割部署方案,聚焦PP-HumanSeg Lite模型在NCNN框架下的C端高效落地,适用于视频会议背景虚化、AR换装、实时抠图等低延迟场景,适合具备C基础和一定CV部署经验的中高级开发者…

2026/10/15 10:38:32 阅读更多 →
OpenGL正背面剔除与深度测试:原理、配置与穿模问题排查

OpenGL正背面剔除与深度测试:原理、配置与穿模问题排查

1. 从一个“穿模”现象说起:为什么需要正背面剔除与深度测试但凡做过3D渲染的人,几乎都遇到过这样的场景:一个封闭的立方体或者角色模型,旋转到某个角度后,本该被挡住的背面却透了出来,或者两个物体交叠的地…

2026/10/15 10:38:32 阅读更多 →
企业WordPress定制开发:核心价值与选型指南

企业WordPress定制开发:核心价值与选型指南

1. 为什么企业需要专业的WordPress定制开发服务 在数字化浪潮席卷各行各业的当下,企业官网已从简单的"电子名片"升级为集品牌展示、客户服务和业务转化于一体的核心平台。WordPress作为全球占比43%的内容管理系统,凭借其开源特性、丰富的插件生…

2026/10/15 10:37:31 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →