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

如何在Pandas中为可变窗口计算前瞻性OHLC时间序列极值?

当然可以!完全不用循环和自定义函数,借助pandas的向量化操作和时间索引特性,就能高效搞定这三个不同时间框架的极值计算需求。下面针对你提到的三个场景逐一拆解实现:

前提准备

首先确保你的DataFrame已经把时间列设为datetime类型的索引(假设时间列名为timestamp):

import pandas as pd

# 假设你的原始数据存放在df中
df = df.set_index('timestamp')
# 确保索引是datetime类型
df.index = pd.to_datetime(df.index)

1. 计算次日(自然日)的价格极值

核心思路是先统计每日的价格极值,再将次日的极值映射回当前数据点:

# 第一步:计算每个自然日的最高价和最低价极值
daily_extremes = df.groupby(df.index.date).agg(
    daily_high_max=('high', 'max'),
    daily_low_min=('low', 'min')
)

# 第二步:将每日极值的索引向后偏移1天(对应次日的极值)
daily_extremes.index = daily_extremes.index + pd.Timedelta(days=1)

# 第三步:将次日极值合并回原DataFrame
df = df.join(daily_extremes, on=df.index.date)

这样daily_high_max和daily_low_min列就对应每个数据点次日的价格极值。

2. 计算未来1小时(后续4行)的价格极值

利用反向滚动窗口实现“向前看”的效果,完全向量化:

# 反转数据后做滚动窗口计算,再反转回来,得到未来4行的极值
df['future_1h_high_max'] = df['high'].iloc[::-1].rolling(window=4).max().iloc[::-1]
df['future_1h_low_min'] = df['low'].iloc[::-1].rolling(window=4).min().iloc[::-1]

原理是:反转数据后,rolling(4)会计算当前行及之前3行的极值,再反转回来就等价于原数据中当前行及之后3行(共4行)的极值,正好对应未来1小时的范围。

3. 计算下周(指定日期起672行)的价格极值

这里我们先定位每个数据点对应的“下周一起始时间”,再批量计算对应672行的极值:

# 第一步:生成所有周一的00:00起始时间点
all_mondays = df.index[df.index.weekday == 0].floor('D').unique()

# 第二步:给每个数据点匹配后续第一个周一的起始时间
df['next_monday_start'] = pd.Series(
    [all_mondays[all_mondays > t].min() for t in df.index],
    index=df.index
)

# 第三步:批量计算每个周一起始点后672行的极值(仅遍历唯一的周一,而非所有数据点)
monday_extremes = {}
for monday in df['next_monday_start'].unique():
    # 找到该周一在索引中的位置
    start_pos = df.index.get_loc(monday)
    # 确保后续有足够的672行数据
    if start_pos + 672 <= len(df):
        monday_extremes[monday] = {
            'next_week_high_max': df['high'].iloc[start_pos:start_pos+672].max(),
            'next_week_low_min': df['low'].iloc[start_pos:start_pos+672].min()
        }

# 第四步:将极值映射回原DataFrame
df['next_week_high_max'] = df['next_monday_start'].map(
    lambda x: monday_extremes[x]['next_week_high_max'] if x in monday_extremes else None
)
df['next_week_low_min'] = df['next_monday_start'].map(
    lambda x: monday_extremes[x]['next_week_low_min'] if x in monday_extremes else None
)

这里的小循环仅针对唯一的周一日期,而非每个数据点,性能几乎不受影响,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:35:22