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

如何在Pandas中实现基于前一行的截断累积和(Clipped Cumsum)

高效实现依赖前值的截断累积和(Clipped Cumsum)

需求明确

先通过energy_pv - energy_consumption生成spare_pv列,再生成cumsum_spare_pv列,规则为:

  • 首行:若spare_pv[0] <= 0则取0,否则取spare_pv[0]
  • 后续行:计算当前spare_pv + 上一行cumsum_spare_pv,结果<=0则取0,否则取该结果

普通的pd.Series.cumsum()无法实现这种带截断且依赖前序计算结果的逻辑,纯Python循环处理数十万行效率极低,以下是高效解决方案:

最优方案:用Numba编译加速循环

Numba能将Python循环编译为机器码,速度比纯Python循环快几十倍甚至上百倍,完全适配数十万行的数据集。

步骤1:计算spare_pv列

import pandas as pd
import numpy as np
from numba import jit

df['spare_pv'] = df['energy_pv'] - df['energy_consumption']

步骤2:定义Numba编译的截断累积和函数

@jit(nopython=True)
def clipped_cumsum(arr):
    result = np.empty_like(arr)
    current = 0.0
    for i in range(len(arr)):
        current += arr[i]
        # 截断逻辑:小于等于0则重置为0
        current = max(current, 0.0)
        result[i] = current
    return result

步骤3:应用函数生成目标列

df['cumsum_spare_pv'] = clipped_cumsum(df['spare_pv'].values)

备选方案:Pandas Expanding Apply(仅适合小数据集)

如果不想引入Numba依赖,可使用Pandas的expanding().apply(),但速度远不如Numba,仅建议用于万级以内的数据集:

def calc_clipped_window(window):
    # 窗口最后一个值是当前spare_pv,前面的累积结果是窗口倒数第二个值(如果存在)
    prev_cumsum = window.iloc[-2] if len(window) > 1 else 0
    current_val = window.iloc[-1] + prev_cumsum
    return max(current_val, 0)

df['cumsum_spare_pv'] = df['spare_pv'].expanding().apply(calc_clipped_window)

结果验证

比如以下测试数据:

energy_consumptionenergy_pvspare_pvcumsum_spare_pv
101555
107-32
107-30
101444

计算结果完全匹配Excel公式=IF((E2+F1)<=0, 0, E2+F1)的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:45:45