You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python最优实现:检查列表元素是否在DataFrame列中并累加流数据

优化实现方案

你的原代码用了双重循环+iterrows()逐行迭代,在数据量较大时效率极低——iterrows()本身就有不小的性能开销,双重循环更是让时间复杂度达到O(M*N)(M是流派数量,N是DataFrame行数)。下面是几种更高效的替代方案:

方案1:利用str.contains()做向量化匹配

如果Genre列的元素是字符串格式(比如每个单元格是"Pop, Indie Folk"这类多流派拼接的字符串),可以直接用pandas的str.contains()快速筛选出包含目标流派的行,再求和:

genre_names = take(1545, all_genres)
streams_on_genre = []
for genre in genre_names:
    # 筛选包含当前流派的行,对Streams列求和,na=False排除缺失值
    total = spotify_data.loc[spotify_data['Genre'].str.contains(genre, na=False), 'Streams'].sum()
    streams_on_genre.append(total)

这个方案依赖pandas的向量化操作,比原代码快几十倍,不需要逐行遍历。

方案2:提前展开流派再分组求和(最优解)

如果你的Genre列每个单元格对应多个流派(不管是字符串分隔、列表还是集合),先把每个流派拆成单独的行,再一次性分组求和,后续查询直接从结果字典中取值:

# 第一步:展开Genre列,每行只保留一个流派
# 假设Genre是逗号分隔的字符串,比如"Pop, Rock",如果是列表直接跳过str.split
expanded_df = spotify_data.assign(Genre=spotify_data['Genre'].str.split(', ')).explode('Genre')

# 第二步:按流派分组,计算总播放量
genre_stream_map = expanded_df.groupby('Genre')['Streams'].sum().to_dict()

# 第三步:从字典中提取目标流派的结果,不存在的流派返回0
genre_names = take(1545, all_genres)
streams_on_genre = [genre_stream_map.get(genre, 0) for genre in genre_names]

这个方案的时间复杂度是O(N + M),只需要一次数据展开和分组,后续查询都是O(1)的字典查找,数据量越大,比原代码的提升越明显,尤其适合需要多次查询不同流派列表的场景。

方案3:针对集合类型的Genre列

如果Genre列的元素是集合(比如每个单元格是{'Pop', 'Indie'}),可以用apply快速判断流派是否在集合中:

genre_names = take(1545, all_genres)
streams_on_genre = []
for genre in genre_names:
    total = spotify_data[spotify_data['Genre'].apply(lambda x: genre in x)]['Streams'].sum()
    streams_on_genre.append(total)

这个方案比原代码高效,避免了iterrows()带来的性能损耗。

内容的提问来源于stack exchange,提问作者zizo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 12:04:55