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

如何加速Python中的get_lags函数?大数据集性能优化求助

优化大DataFrame滞后列生成的实战方案

嘿,我之前处理过类似的超大表滞后操作问题,那种跑半天没反应的痛苦太懂了!咱们来一步步拆解问题、优化你的get_lags函数:

先搞清楚为啥慢

  1. 逐列循环的低效:如果你的函数是用Python循环遍历每一列单独做shift,那2万列的循环会把Pandas的向量化优势完全浪费——Python层面的循环本身就慢,更别说每列都要单独处理数据。
  2. 内存爆炸拖垮速度:10万行×2万列的原数据已经占了不少内存(比如float64的话,10w×2w×8字节≈16GB,刚好卡你的内存上限),再生成2倍的滞后列,内存直接溢出,系统开始频繁磁盘交换(swap),这时候CPU再强也跑不动。
  3. 没利用Pandas的底层优化:如果手动处理列名或者移位逻辑,可能绕开了Pandas内部的C级别的高效操作。

具体优化方案

1. 用全DataFrame批量移位(最核心的提速)

别逐列处理,直接对整个DataFrame做shift,然后批量重命名列——Pandas会用底层的向量化操作,速度能提升几个数量级:

import pandas as pd

def get_lags(df, n_lags):
    # 先收集所有滞后DataFrame
    lag_frames = []
    for lag in n_lags:
        # 对整个df移位,而不是逐列
        shifted = df.shift(lag)
        # 批量重命名列
        shifted.columns = [f"{col}_lag{lag}" for col in df.columns]
        lag_frames.append(shifted)
    # 把原数据和所有滞后列合并(如果不需要原数据可以去掉df)
    return pd.concat([df] + lag_frames, axis=1)

2. 砍内存!从根源解决卡顿

你的内存刚好16GB,原数据几乎占满,必须先优化数据类型:

  • 把float64转成float32(如果业务允许精度损失),直接砍半内存:
    # 先检查数据类型,再批量转换
    df = df.astype({col: 'float32' for col in df.select_dtypes('float64').columns})
    
  • 整数类型同理,比如int64转int32甚至int16(看数值范围)。
  • 如果不需要保留原数据,就别把原df和滞后列合并,直接返回滞后列的合并结果,能省一半内存。
  • 极端情况:分块处理。把2万列分成多个块(比如每5000列一块),处理完一块就保存到磁盘(比如用Parquet格式,压缩率高),最后再合并,避免一次性占满内存。

3. 用Dask做并行/外存处理

如果优化内存后还是卡,可以试试Dask——它能把数据拆成小块并行处理,甚至不把全量数据加载到内存:

import dask.dataframe as dd

def get_lags_dask(df, n_lags):
    lag_frames = []
    for lag in n_lags:
        shifted = df.shift(lag)
        shifted = shifted.rename(columns={col: f"{col}_lag{lag}" for col in df.columns})
        lag_frames.append(shifted)
    return dd.concat([df] + lag_frames, axis=1)

# 使用示例:从CSV加载或从Pandas转Dask DataFrame
ddf = dd.from_pandas(df, npartitions=4)  # 分4块并行
result_ddf = get_lags_dask(ddf, [1,2])
# 可以直接保存到磁盘,不用全量加载到内存
result_ddf.to_parquet('lagged_data.parquet')
# 或者需要的时候再compute成Pandas df
result_df = result_ddf.compute()

4. 调整Windows环境的Pandas配置

Windows上默认的Pandas可能没开全线程,你可以:

  • 确保用的是带MKL优化的Pandas(比如Anaconda安装的版本,比官方pip版快很多)。
  • 关掉不必要的链式赋值警告,避免额外开销:
    pd.set_option('mode.chained_assignment', None)
    

测试建议

先拿小数据量验证优化后的函数逻辑是否正确(比如1000行100列),确认没问题再跑全量数据——不然全量跑半天发现逻辑错了就亏大了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:04:34