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

如何在pandas中高效对250MB DataFrame执行90次移位、拼接与除法操作

预期合理性判断

你的数分钟完成的预期完全合理,优化后的方案甚至可以在1分钟内完成运算。你之前的方案性能差、内存占用高主要来自两个问题:

  • 循环拼接全量DataFrame,每次拼接都会触发全量数据拷贝,90次循环会产生大量冗余内存开销
  • 自定义apply函数逻辑错误(循环内直接return只会返回w=1的计算结果),且自定义apply的矢量化程度远低于pandas内置函数,性能损耗严重

优化方案

方案1:pandas原生函数实现(易维护,性能足够)

核心优化点:预存分组对象避免重复分组,所有计算结果暂存列表后一次性拼接,避免多次全量拷贝。

import pandas as pd

# 预定义需要处理的列
target_cols = ["c1", "c2", "c3", "c4", "c5"]
# 预存分组对象,避免重复计算分组
gb = data.groupby(level="mylevel")[target_cols]

res_list = []
for w in range(1, 91):
    # 直接使用内置shift计算,矢量化运算效率远高于自定义apply
    div_result = gb.shift(w) / gb.shift(w-1)
    # 可指定float32类型,内存占用直接减半
    div_result = div_result.astype("float32")
    # 重命名列
    div_result.columns = [f"{col}_{w}" for col in target_cols]
    res_list.append(div_result)

# 一次性拼接所有结果
final_df = pd.concat(res_list, axis=1)

方案2:Numpy优化版(性能更强,适合极致提速需求)

如果需要进一步压缩运行时间,可以把分组后的数据转为numpy数组运算,避免pandas的行索引 overhead:

import numpy as np
import pandas as pd

target_cols = ["c1", "c2", "c3", "c4", "c5"]
# 确保数据已经按分组+时间维度排序,移位结果才正确
data = data.sort_index()
# 提取分组边界
group_sizes = data.groupby(level="mylevel").size().values
# 转numpy数组
arr = data[target_cols].values
rows, cols = arr.shape
# 初始化结果数组
res_arr = np.full((rows, cols * 90), np.nan, dtype=np.float32)

offset = 0
for size in group_sizes:
    group_data = arr[offset:offset+size]
    for w in range(1, 91):
        if w >= size:
            continue
        # numpy索引移位计算,比pandas shift快3-5倍
        res_arr[offset + w : offset + size, w*cols : (w+1)*cols] = group_data[:size - w] / group_data[1: size - w + 1]
    offset += size

# 生成列名
col_names = [f"{col}_{w}" for w in range(1,91) for col in target_cols]
final_df = pd.DataFrame(res_arr, index=data.index, columns=col_names)

内存优化提示

最终结果如果使用float32存储,1100万行 * 450列的内存占用约为19GB,属于常规服务器可以承受的范围,如果内存不足可以考虑按分组分批计算后再拼接结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:30:04