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

如何在Pandas中实现类似SQL带分组滞后参数的计算?

Pandas 实现SQL分区Lag函数的简洁写法

原SQL实现逻辑

在SQL中,我们可以通过窗口函数快速实现带分区的滞后指标计算,示例如下:

CASE
   WHEN dt_rep.fcr = 0::numeric THEN 0::numeric
                ELSE (dt_rep.fcr - lag(dt_rep.fcr) OVER (PARTITION BY dt_rep.place_id ORDER BY dt_rep.bucket)) / dt_rep.fcr
END AS cr

这段代码按place_id分区、bucket排序,用lag函数计算cr,最后过滤cr为null的行得到结果。

Pandas常规实现(需临时列)

在Pandas中常规做法是先生成分组移位的临时列,再计算目标列:

data_fin['fcr_b'] = data_fin.groupby(['place_id'])['fcr'].shift(1)
# 后续计算cr:(data_fin['fcr'] - data_fin['fcr_b']) / data_fin['fcr'],再处理fcr=0的情况,最后过滤NaN

更简洁的直接实现方法

可以跳过临时列,直接在分组操作中完成cr列的计算,以下是两种简洁写法:

写法1:分组apply链式处理

# 直接计算cr,同时处理fcr=0的情况
data_fin['cr'] = data_fin.groupby('place_id')['fcr'].apply(
    lambda x: (x - x.shift(1)) / x
).where(data_fin['fcr'] != 0, 0)

# 过滤掉每组第一行(移位后为NaN的行)
data_fin = data_fin.dropna(subset=['cr'])

写法2:用assign链式调用,全程无临时变量

data_fin = (
    data_fin
    .assign(
        cr=lambda df: df.groupby('place_id')['fcr']
                       .apply(lambda x: (x - x.shift(1)) / x)
                       .where(df['fcr'] != 0, 0)
    )
    .dropna(subset=['cr'])
)

核心说明

  • x.shift(1)等价于SQL中的lag(dt_rep.fcr),默认滞后1行
  • where方法对应SQL的CASE WHEN逻辑,当fcr=0时返回0,否则执行计算
  • dropna(subset=['cr'])对应SQL中过滤cr为null的操作,移除每组的第一行(无滞后值的行)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:53:24