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

如何在Pandas中添加3天后Close值的滚动列(无循环实现)

问题描述

我有一个包含Date、Open、High、Low、Close字段的股票Pandas DataFrame,数据如下:

DateOpenHighLowClose
2019-12-30216221213220
2019-12-31241250229243
2020-01-01239242217229
2020-01-02244252234249

希望在Pandas中新增一列Rolling,该列展示每行日期3天后的Close值(用于计算3日收益率),预期效果如下:

DateOpenHighLowCloseRolling说明
2019-12-30216221213220249对应2020-01-02的Close值(3天后)
2019-12-31241250229243252对应2020-01-03的Close值(3天后)
2020-01-01239242217229对应2020-01-04的Close值(无数据则空)
2020-01-02244252234249对应2020-01-05的Close值(无数据则空)
2020-01-03249256244252对应2020-01-06的Close值(无数据则空)

要求提供无需使用for循环的实现方案。

实现方案

场景1:连续交易日数据(无缺失)

如果股票数据按连续交易日排列(无周末/节假日缺失),直接使用shift方法即可高效实现:

import pandas as pd

# 确保Date列为日期类型
df['Date'] = pd.to_datetime(df['Date'])

# 新增Rolling列,取当前行之后第3行的Close值
df['Rolling'] = df['Close'].shift(-3)

场景2:严格按自然日偏移(含非交易日)

如果需要严格匹配自然日3天后的Close值(不管中间是否有交易日),按以下步骤实现:

import pandas as pd

# 1. 转换Date列为日期类型并设为索引
df['Date'] = pd.to_datetime(df['Date'])
df = df.set_index('Date')

# 2. 生成包含所有自然日的序列(从数据最小日期到最大日期+3天)
full_date_range = pd.date_range(
    start=df.index.min(),
    end=df.index.max() + pd.Timedelta(days=3)
)

# 3. 重新索引补全所有日期,缺失的Close值填充为NaN
full_df = df.reindex(full_date_range)

# 4. 偏移3天获取对应Close值
full_df['Rolling'] = full_df['Close'].shift(-3)

# 5. 还原回原始数据的日期并重置索引
df = full_df.loc[df.index].reset_index().rename(columns={'index': 'Date'})

关键说明

  • shift(-3)是Pandas内置的向量化操作,完全避免了for循环,执行效率远高于循环遍历。
  • 连续交易日场景下,shift(-3)直接对应3个交易日后的Close值;自然日场景下,通过补全日期序列确保严格匹配3天后的日期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:40:49