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

如何借助numexpr与Dask进一步优化大型pandas DataFrame的运算性能?

优化大型DataFrame逐元素运算的方案:Dask及其他方法

一、使用Dask实现并行分块计算

如果数据集大到单进程内存处理吃力,Dask是最优选择之一,它通过分块并行计算充分利用多核CPU,同时避免内存溢出。

示例代码:

import dask.dataframe as dd

# 用Dask读取CSV,自动按内存情况分块
ddf = dd.read_csv('large_data.csv')

# 直接执行逐元素运算,Dask会延迟计算(此时不会实际执行)
ddf['new_column'] = ddf['column1'] + ddf['column2']

# 触发计算,可选择转成pandas DataFrame或保留Dask格式后续处理
df = ddf.compute()

优势:

  • 自动分块并行,无需手动拆分数据;
  • 支持超出内存的大数据处理,只加载当前计算需要的块;
  • 底层会自动选择最优计算策略(包括可能调用numexpr优化),无需额外配置。

二、其他可落地的优化方向

1. 优化数据读取环节

读取数据是很多大型任务的性能瓶颈,优化这里能显著节省时间:

  • 指定数据类型:避免pandas自动推断类型,减少内存占用和读取耗时:
    df = pd.read_csv('large_data.csv', dtype={'column1': 'float32', 'column2': 'float32'})
    
  • 只加载需要的列:用usecols跳过无关列,减少内存开销:
    df = pd.read_csv('large_data.csv', usecols=['column1', 'column2'])
    
  • 转用高效存储格式:将CSV转存为Parquet或Feather,读取速度比CSV快数倍,且支持列存储:
    # 一次性转存(后续直接读取Parquet)
    df.to_parquet('large_data.parquet')
    # 快速读取
    df = pd.read_parquet('large_data.parquet')
    

2. 压缩内存占用

内存占用越小,CPU缓存命中率越高,运算速度越快:

  • 降低数值类型精度:在数据范围允许的情况下,将float64转float32、int64转int32:
    df['column1'] = df['column1'].astype('float32')
    df['column2'] = df['column2'].astype('float32')
    

3. 对比pandas原生向量化运算

pandas的原生向量化运算(df['column1'] + df['column2'])底层基于numpy优化,在某些场景下和numexpr的性能差距极小,甚至更快(比如CPU核心数较少时)。可以直接测试两者耗时,选择最优方案。

4. 用swifter自动选择最优计算策略

swifter库会自动检测运算类型,优先使用向量化,若不支持则切换到numexpr或Dask并行,简化优化流程:

import swifter

df['new_column'] = df.swifter.apply(lambda x: x['column1'] + x['column2'], axis=1)

注:对于简单逐元素运算,swifter会自动识别并使用原生向量化,无需lambda,直接写df['new_column'] = df['column1'] + df['column2']即可,原生向量化本身已经足够高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:21:35