如何在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
相关产品推荐
相关产品推荐

