直接用 value_counts() 替代 drop_duplicates() + groupby().size() 可提速2–3倍并避免内存爆炸,因其底层复用哈希聚合逻辑;对多列组合统计频次时,df[['a','b']].value_counts(sort=false) 是单步最优解。

直接用 drop_duplicates() + value_counts() 会爆内存或卡死——这不是数据量大,是方法没选对。
为什么 drop_duplicates() 在大数据下很慢?
它默认保留首次出现的行,内部需要维护全局哈希表和索引映射,内存占用随行数线性增长;当数据超千万行时,GC 压力大、CPU cache 友好性差,且无法流式处理。
- 真实场景中,
df.drop_duplicates(subset=['a','b'])对 5000 万行 DataFrame 可能吃掉 12GB 内存 - 若只关心去重后计数(而非保留哪一行),完全没必要构建完整去重结果
-
value_counts(sort=False)比先drop_duplicates()再groupby().size()快 2–3 倍,因底层复用哈希聚合逻辑
用 value_counts() 替代“去重+计数”两步走
只要目标是统计每个唯一组合出现次数,value_counts() 就是单步最优解,它本质就是带计数的去重。
- 对单列:
df['col'].value_counts(dropna=False)—— 默认已去重并计数 - 对多列组合:
df[['a','b','c']].value_counts(dropna=False)—— 返回MultiIndexSeries,值即频次 - 加
sort=False能跳过排序开销,提速 15%~40%,尤其当结果量级达百万级时 - 注意:
value_counts()默认忽略 NaN,需显式设dropna=False才把NaN当作独立值参与计数
超大数据(>1亿行)必须分块 + pd.concat() 合并计数
单次加载全量数据不可行,但不能简单用 chunksize 然后逐块 value_counts() 再相加——不同块里的相同 key 会被重复计数,且合并时 MultiIndex 对齐成本高。
- 正确做法:每块调用
value_counts(sort=False),用pd.concat(..., axis=0)拼成一个大 Series,再调用.groupby(level=[0,1,...]).sum() - 示例关键代码:
counts_list = [] for chunk in pd.read_csv('big.csv', chunksize=500000): c = chunk[['user_id','action']].value_counts(sort=False) counts_list.append(c) total = pd.concat(counts_list).groupby(level=[0,1]).sum() - 避免用
dict手动累加——Pandas 的groupby().sum()对SerieswithMultiIndex效率远高于 Python 循环 - 如果磁盘 I/O 是瓶颈,考虑用
dask.dataframe或polars替代,但要注意polars.DataFrame.unique(maintain_order=False)不带计数,得配合group_by().len()
去重后还要保留某条原始记录?别硬扛,换思路
如果业务要求“每个唯一键只留时间最新的那条”,就不是纯计数问题了,drop_duplicates() 仍不可避免,但可大幅优化。
- 先按关键字段 + 时间字段排序:
df.sort_values(['key1','key2','timestamp'], ascending=[True,True,False]) - 再用
drop_duplicates(subset=['key1','key2'], keep='first')—— 此时“first”就是最新时间那条 - 排序本身开销大,但比无序下全局哈希去重要快;若已有索引或分区,优先利用
partition_cols(如 PyArrow / Parquet)跳过部分扫描 - 真正卡住的往往不是 Pandas,而是 CSV 解析——换成
pd.read_parquet()或pd.read_feather()可减少 60%+ 加载时间
最常被忽略的一点:value_counts() 返回的 Series 默认 index 是 MultiIndex,直接写入 CSV 会变成多列带空格的字符串;导出前记得用 reset_index(name='count') 拉平结构——这个坑在 pipeline 中一踩就断链。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











