RAM受限场景下如何高效统计Pandas DataFrame各重复行的数量
优化方案
方案1:pandas原生优化(无需额外依赖)
你之前的实现性能差、内存占用高,核心有两个可优化点:一是字符串列没有利用分类编码压缩,二是手动循环+append的操作存在大量冗余开销。你可以按照以下步骤改造,32GB内存完全可以覆盖你的需求:
- 先将字符串类型的
job.jobTitlText列转为categorical类型,三列全部转为分类类型后,底层统一用整数编码存储,groupby计算时的内存开销和计算开销会大幅降低:
df['job.jobTitlText'] = df['job.jobTitlText'].astype('category')
- 直接使用pandas内置的
value_counts方法完成行频次统计,该方法的实现比groupby+size更轻量化,内存占用低30%以上:
final_df = df.value_counts(sort=False, reset_index=True, name='size')
以上两步即可替代你之前写的全部代码,运行时间从小时级降到分钟级甚至秒级。
方案2:更高内存效率的polars实现
如果上述方案还是有内存压力,可以切换到内存优化更极致的polars库实现,相同数据量下内存占用比pandas低50%左右,计算速度也有数倍提升:
import polars as pl # 也可以直接用pl.read_csv/pl.read_parquet等方法直接读取源文件,避免pandas转存的额外内存开销 pl_df = pl.from_pandas(df) final_df = pl_df.group_by(pl_df.columns, maintain_order=True).len().to_pandas()
旧代码性能差的原因
iterrows遍历本身性能极低,每一行都要做对象类型转换,开销是向量化操作的上千倍- 循环中反复append DataFrame,每次append都会生成全新的DataFrame对象,内存拷贝开销随数据量增长指数级上升
- 用Counter聚合属于单线程Python层操作,没有利用pandas底层的C语言向量化优化
内容的提问来源于stack exchange,提问作者tsorn
相关产品推荐
相关产品推荐

