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

如何通过一次groupby调用创建Pandas多列不同滞后值

分组生成命名滞后特征的高效实现

核心需求

  • 最终目标:给Pandas DataFrame按分组生成n个带命名的滞后特征(每行对应分组内的历史值)
  • 次要目标:减少Pandas API调用次数,避免嵌套for循环

朴素实现(低效)

下面是常规的嵌套循环写法,需要调用len(features)*n次API,效率偏低:

n = 7
for feature in features:
    for i in range(1, n + 1):
        df[feature + "_" + str(i)] = df.groupby(["a", "b"])[feature].shift(i)

失败的优化尝试

想用agg方法批量生成滞后特征,但agg要求聚合函数返回单个值,不支持shift这类保留原行数的操作,运行后会报错ValueError: Must produce aggregated value:

lagged_features = {}
n = 7
for feature in features:
    for i in range(1, n + 1):
        key = feature + "_" + str(i)
        lagged_features[key] = pd.NamedAgg(feature, lambda x: x.shift(i))

df_lagged = df.groupby(["a", "b"]).agg(**lagged_features)

高效实现方案(仅1次API调用)

利用groupby.shift的向量化特性,一次性生成所有滞后特征,再整理列名即可:

import pandas as pd

n = 7
# 按分组批量生成1到n阶滞后
lagged_df = df.groupby(["a", "b"])[features].shift(range(1, n+1))
# 重命名列:格式为「原特征名_滞后阶数」
lagged_df.columns = [f"{col}_{i+1}" for col in features for i in range(n)]
# 合并到原DataFrame
df = pd.concat([df, lagged_df], axis=1)

原理说明

  • shift(range(1, n+1))会对每个特征同时生成1到n阶的滞后结果,返回的DataFrame会有多层列索引(第一层是原特征名,第二层是滞后阶数)
  • 通过列表推导式把多层索引转换成直观的命名格式
  • 最后用concat把滞后特征拼回原表,全程只调用一次groupby.shift,完全避免嵌套循环

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:33:25