16GB内存下1000万行数据集的pandas性能优化方法求助
Pandas千万级数据集性能优化最佳实践
1. 内存管理技巧
- 优化数据类型
- 将重复率高的字符串列转为
category类型:df['category_col'] = df['category_col'].astype('category'),内存占用可降至原来的1/10甚至更低 - 降级数值类型:用
pd.to_numeric(df['int_col'], downcast='integer')或pd.to_numeric(df['float_col'], downcast='float')自动匹配最小可用数值类型,避免默认的int64/float64浪费内存 - 杜绝混合类型列:混合类型会触发
objectdtype,内存占用极高,提前统一列类型
- 将重复率高的字符串列转为
- 按需加载数据
- 用
usecols指定仅加载需要的列:pd.read_csv('data.csv', usecols=['col1', 'col3', 'col5']) - 分块读取处理:通过
chunksize参数拆分数据集,分批完成清洗/转换后再合并:for chunk in pd.read_csv('data.csv', chunksize=100000): process(chunk)
- 用
- 清理冗余数据
- 删除空值占比过高的列:
df.dropna(axis=1, thresh=len(df)*0.2)(保留至少20%非空值的列) - 移除重复行:
df.drop_duplicates(subset=['key_col1', 'key_col2'], inplace=True)
- 删除空值占比过高的列:
2. 高效执行GroupBy与Apply的方法
- 优先使用内置聚合函数
放弃自定义apply,改用groupby().agg()指定内置聚合逻辑,比如:df.groupby('group_key').agg({'value_col': ['sum', 'mean'], 'count_col': 'count'}),内置函数基于C实现,性能比Python级apply高一个数量级 - 用Transform替代Apply做逐行分组计算
比如给每行添加组内均值,用df['group_mean'] = df.groupby('group_key')['value_col'].transform('mean'),避免遍历每个分组的额外开销 - 优化自定义Apply(迫不得已时)
- 函数内部尽量用Pandas/NumPy向量操作,避免Python循环
- 用
@numba.jit装饰器加速数值密集型函数,减少解释器开销
- 预排序分组键
对分组列排序后再执行groupby:df.sort_values('group_key', inplace=True),Pandas对有序数据的分组操作有底层优化
3. Pandas替代方案(针对超大规模数据集)
- Dask DataFrame:兼容Pandas API,自动分块并行计算,无需修改太多代码即可处理内存装不下的数据集,核心用法:
import dask.dataframe as dd; dd_df = dd.read_csv('data.csv'); result = dd_df.groupby('group_key').sum().compute() - Polars:性能远超Pandas的新兴DataFrame库,原生支持多核并行,对GroupBy、Join等操作优化极强,语法与Pandas接近,学习成本低
- Vaex:基于内存映射技术,无需将全量数据加载到内存,支持快速过滤、聚合和可视化,适合TB级数据集
4. 并行处理与多核利用建议
- Pandarallel库快速实现并行Apply
初始化后直接给groupby apply加上并行能力:from pandarallel import pandarallel pandarallel.initialize(nb_workers=4) # 匹配CPU核心数 df.groupby('group_key').apply(parallel_process_func) - 分块+多进程手动并行
将数据集拆分为多个块,用multiprocessing.Pool并行处理后合并结果,适合复杂的自定义处理逻辑 - Numba加速自定义函数
对数值计算密集型的函数添加@numba.jit(nopython=True)装饰,将Python代码编译为机器码,性能提升显著 - 避免进程间数据传递开销
并行函数尽量使用局部变量,避免依赖全局大对象,减少进程间的数据拷贝
内容的提问来源于stack exchange,提问作者Olusoji
相关产品推荐
相关产品推荐

