使用Pandas drop_duplicates处理歌曲数据集时删除过多行的问题排查
问题分析与解决方案
从你描述的现象和代码来看,出现这种极端去重结果的原因主要集中在以下几个方面,我们逐一拆解:
1. keep='last'参数的行为导致只保留末尾少数唯一行
你在drop_duplicates中使用了keep='last',这个参数的核心作用是:对于每一组重复的行,只保留最后一次出现的那一行,删除之前所有的重复项。
结合你提到的“结果数据集从第8700行开始”,这说明你的数据集前8700行左右的内容,几乎都是后面某些行的重复拷贝:
- 比如你可能多次导入了同一批已喜欢歌曲,导致前8000多行都是少数歌曲的重复版本;
- 这些重复行的最后一次出现都集中在8700行之后,所以去重后只保留了这些末尾的重复项,加上少量真正唯一的歌曲,最终只剩196行。
需要注意的是,你之前计算重复行数时用的data.duplicated(subset=...)是默认keep='first',它标记的是除第一次出现外的所有重复行,得到的10904是“非首次出现的重复行”数量。但drop_duplicates(keep='last')删除的是除最后一次出现外的所有重复行,两者统计逻辑不同,所以直接用前者的数字预判后者的结果会有偏差。
2. 去重的子集字段无法唯一标识歌曲
你选择track_name、first_artist、duration_ms作为去重依据,但这三个字段的组合并不一定能精准区分不同歌曲:
- 存在同名同艺术家但不同版本的歌曲(比如现场版、混音版、专辑版),它们的时长可能因为数据精度问题被存储为相同的
duration_ms值; - 不同歌曲可能恰好同名、同艺术家、时长近似(比如不同专辑里的同名歌曲,时长只差几毫秒,但被四舍五入成相同的毫秒数);
- 如果你的
duration_ms字段存在缺失或者异常值(比如大量行的时长都是0),也会导致大量无关行被误判为重复。
3. 已喜欢与未喜欢歌曲存在大量交叉重复
你提到未喜欢歌曲没有内部重复,但没说明已喜欢和未喜欢的歌曲之间没有重复。如果同一首歌既出现在已喜欢列表,又出现在未喜欢列表,那么keep='last'会只保留最后出现的那一条(也就是未喜欢列表里的版本)。如果你的数据集是先排列已喜欢歌曲、再排列未喜欢歌曲,那么大量已喜欢的重复行都会被删除,只保留未喜欢的版本,但结合你只剩196行的结果来看,这种情况可能只是辅助因素。
验证与修复建议
验证问题根源
- 查看去重后数据的分布:
# 查看去重后数据的原行号范围 print(data.index.min(), data.index.max()) # 查看去重后已喜欢/未喜欢歌曲的数量(假设你有标记字段如'is_liked') print(data['is_liked'].value_counts()) - 检查哪些组合被判定为重复:
# 找出重复次数最多的歌曲组合 duplicate_groups = data.groupby(['track_name', 'first_artist', 'duration_ms']).size().sort_values(ascending=False) print(duplicate_groups.head(20)) - 对比
keep='first'和keep='last'的去重结果:data_first = data.drop_duplicates(subset=['track_name', 'first_artist', 'duration_ms'], keep='first') print(len(data_first)) # 看看保留首次出现的版本会有多少行
修复方案
- 如果你的目标是保留所有唯一歌曲(不管喜欢与否)且希望保留首次出现的版本,将
keep参数改为'first'; - 如果
duration_ms的精度有问题,可以考虑将其转换为秒(取整)或者放宽匹配条件(比如允许时长差在1000毫秒内); - 尝试加入更多唯一标识字段(比如
track_id,如果数据集里有),这样能更精准地去重。
内容的提问来源于stack exchange,提问作者Ece Akdeniz
相关产品推荐
相关产品推荐

