每年,Spotify 用户都热切地等待 Spotify Wrapped 的发布,这是一份个性化的年度回顾,展示了他们最常听的歌曲、艺术家和流派。如果我告诉您有一种方法可以在正式发布之前先睹为快您的 Spotify 统计数据,您会怎样?
在本指南中,我将引导您完成 Spotify Wrapped hack,它允许您使用 Spotify 流数据创建您自己的个性化统计数据。这样您就不需要等待 Spotify Wrapped,而且您还可以创建 Spotify 不会向您显示的统计数据。
与我之前的一个项目类似,我们将使用 Jupyter Notebook 来完成这个项目。它是实验和处理数据的绝佳工具。
如果您尚未安装 Jupyter Notebook,请按照其官方网站上的说明进行操作。安装后,您可以创建一个新的 Jupyter Notebook 并准备好深入了解您的 Spotify 统计数据。
首先,您需要请求 Spotify 流媒体数据。您可以在此处执行此操作(确保您请求“扩展流媒体历史记录”)。 Spotify 需要一些时间才能向您发送数据。仅请求“帐户数据”会更快,并且还会为您提供去年的流媒体历史记录。但是,它不太详细,您必须调整代码。
获得数据后,我们就可以导入它。您将获得多个 JSON 文件。每个文件由一组对象组成,其中包含有关播放的歌曲或播客剧集的信息:
{ "ts": "2023-01-30T16:36:40Z", "username": "", "platform": "linux", "ms_played": 239538, "conn_country": "DE", "ip_addr_decrypted": "", "user_agent_decrypted": "", "master_metadata_track_name": "Wonderwall - Remastered", "master_metadata_album_artist_name": "Oasis", "master_metadata_album_album_name": "(What's The Story) Morning Glory? (Deluxe Remastered Edition)", "spotify_track_uri": "spotify:track:7ygpwy2qP3NbrxVkHvUhXY", "episode_name": null, "episode_show_name": null, "spotify_episode_uri": null, "reason_start": "remote", "reason_end": "remote", "shuffle": false, "skipped": false, "offline": false, "offline_timestamp": 0, "incognito_mode": false }
这不仅可以让您弄清楚您何时以及在哪个设备上收听了歌曲,还可以为您提供诸如是否以及何时跳过这首歌等信息。
我们将简单地将它们全部合并到一个 Pandas 数据框中:
path_to_json = 'my_spotify_data/' frames = [] for file_name in [file for file in os.listdir(path_to_json) if file.endswith('.json')]: frames.append(pd.read_json(path_to_json + file_name)) df = pd.concat(frames)
之后,我们将通过删除播客、过滤掉短播放持续时间并将时间戳转换为更易读的格式来对其进行清理:
# drop all rows containing podcasts df = df[df['spotify_track_uri'].notna()] # drop all songs which were playing less than 15 seconds df = df[df['ms_played'] > 15000] # convert ts from string to datetime df['ts'] = pd.to_datetime(df['ts'], utc=False) df['date'] = df['ts'].dt.date # drop all columns which are not needed columns_to_keep = [ 'ts', 'date', 'ms_played', 'platform', 'conn_country', 'master_metadata_track_name', 'master_metadata_album_artist_name', 'master_metadata_album_album_name', 'spotify_track_uri' ] df = df[columns_to_keep] df = df.sort_values(by=['ts']) songs_df = df.copy()
让我们从探索您一直以来最喜欢的歌曲开始吧。我们可以根据您的流媒体历史记录轻松揭晓我们的热门曲目:
df = songs_df.copy() df = df.groupby(['spotify_track_uri']).size().reset_index().rename(columns={0: 'count'}) df = df.sort_values(by=['count'], ascending=False).reset_index() df = df.merge(songs_df.drop_duplicates(subset='spotify_track_uri')) df = df[['master_metadata_track_name', 'master_metadata_album_artist_name', 'master_metadata_album_album_name', 'count']] df.head(20)
对今年的音乐趋势感到好奇吗?我们可以使用这个函数来揭示 2023 年的热门歌曲:
def top_songs_in_year(year): df = songs_df.copy() df['year'] = df['ts'].dt.year df = df.loc[(df['year'] == year)] print(f"Time listened in {year}: {datetime.timedelta(milliseconds=int(df['ms_played'].sum()))}") df = df.groupby(['spotify_track_uri']).size().reset_index().rename(columns={0: 'count'}) df = df.sort_values(by=['count'], ascending=False).reset_index() df = df.merge(songs_df.drop_duplicates(subset='spotify_track_uri')) df = df[['master_metadata_track_name', 'master_metadata_album_artist_name', 'master_metadata_album_album_name', 'count']] return df.head(20)
这已经很有效了,但为什么要满足于此呢?我们可以使用交互式小部件来使用 UI 元素自定义查询。这使我们能够轻松找到您在任何特定时间范围内的热门歌曲:
@interact def top_songs(date_range=date_range_slider): df = songs_df.copy() time_range_start = pd.Timestamp(date_range[0]) time_range_end = pd.Timestamp(date_range[1]) df = df.loc[(df['date'] >= time_range_start.date()) & (df['date'] <= time_range_end.date())] df = df.groupby(['spotify_track_uri']).size().reset_index().rename(columns={0: 'count'}) df = df.sort_values(by=['count'], ascending=False).reset_index() df = df.merge(songs_df.drop_duplicates(subset='spotify_track_uri')) df = df[['master_metadata_track_name', 'master_metadata_album_artist_name', 'master_metadata_album_album_name', 'count']] return df.head(20)
现在我们知道了我们的热门歌曲、热门艺术家和热门专辑,我们可以更进一步。例如,探索一周中的哪几天我们在 Spotify 上最活跃:
def plot_weekday_distribution(): df = songs_df.copy() df['year'] = df['ts'].dt.year df['weekday'] = df['ts'].dt.weekday df = df.groupby(['year', 'weekday']).size().reset_index(name='count') fig, ax = plt.subplots(figsize=(12, 8)) for year, data in df.groupby('year'): ax.plot(data['weekday'], data['count'], label=str(year)) weekdays_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] plt.xticks(range(7), weekdays_order) plt.title('Weekday Distribution of Played Tracks Over Years') plt.xlabel('Weekday') plt.ylabel('Number of Played Tracks') plt.legend(title='Year') plt.show()
准备好深入了解您自己的 Spotify 统计数据了吗?查看我的GitHub 存储库以查找所有代码,包括更多用于探索听力统计数据的函数。
在正式发布之前创建您的 Spotify 统计数据不仅增加了乐趣,还可以深入了解您独特的收听习惯。正如我们热切期待 Spotify Wrapped 一样,为什么不先开始您的音乐分析冒险呢?
准备好享受您的个性化 Spotify Wrapped 体验!