如何用1小时滚动窗口计算非规则时间序列的标准差?含zoo实操需求
非规则时间序列的1小时滚动窗口标准差计算(base R + zoo实现)
我来帮你解决这个非规则时间序列的滚动标准差计算问题!针对你提出的「每5分钟计算一次过去1小时内px的标准差」需求,我们可以用base R结合zoo包来实现,逻辑清晰且完全符合你的偏好,一步步来:
核心思路
因为你的原始数据是非规则时间序列,不能直接用基于观测数量的滚动窗口函数(比如rollapply默认的窗口),我们需要:
- 生成你要求的「每5分钟」的规则时间序列,作为计算的时间节点
- 对每个时间节点,筛选出过去1小时范围内的所有原始数据
- 计算这些数据的标准差(注意处理样本量不足的情况)
具体代码实现
1. 先确认你的原始zoo对象
首先我们先把你提供的代码再确认一遍,确保数据正确加载:
library(zoo) prices.zoo <- read.zoo(data.frame( tm = c(as.POSIXct('2000-05-10 07:50:00'), as.POSIXct('2000-05-10 08:55:00'), as.POSIXct('2000-05-10 09:00:00'), as.POSIXct('2000-05-10 09:10:00'), as.POSIXct('2000-05-10 09:20:00'), as.POSIXct('2000-05-10 09:55:00'), as.POSIXct('2000-05-10 11:35:00')), px = c(10,20,30,40,50,60,70) ))
2. 生成规则的5分钟时间序列
我们需要从原始数据的最早时间到最晚时间,生成每5分钟一个的时间节点:
# 获取原始数据的时间范围 start_time <- start(prices.zoo) end_time <- end(prices.zoo) # 生成5分钟间隔的规则时间序列 regular_times <- seq.POSIXct(from = start_time, to = end_time, by = "5 mins")
3. 定义滚动标准差计算函数
写一个函数,接收一个时间点,返回该点过去1小时内px的标准差(如果数据量≥2才计算,否则返回NA,因为单值的标准差没有意义):
calc_rolling_sd <- function(current_time, zoo_data, window_hours = 1) { # 计算窗口的起始时间:当前时间往前推1小时 window_start <- current_time - window_hours * 3600 # 筛选出时间在[window_start, current_time]范围内的观测 window_data <- zoo_data[index(zoo_data) >= window_start & index(zoo_data) <= current_time] # 根据数据量返回结果 if (length(window_data) >= 2) { sd(window_data) } else { NA_real_ } }
4. 批量计算每个时间节点的标准差
用sapply遍历所有规则时间节点,计算对应的标准差:
# 计算所有时间点的滚动标准差 rolling_sd_values <- sapply(regular_times, calc_rolling_sd, zoo_data = prices.zoo) # 转成zoo对象(方便后续时间序列操作) rolling_sd_zoo <- zoo(rolling_sd_values, order.by = regular_times) # 或者转成data.frame(适合查看和导出) rolling_sd_df <- data.frame( timestamp = regular_times, rolling_sd_px = rolling_sd_values )
5. 可选:仅在原始观测时间点计算
如果你不需要每5分钟的规则节点,只想在原始数据的每个时间点计算过去1小时的标准差,直接对原始时间应用函数即可:
original_time_sd <- sapply(index(prices.zoo), calc_rolling_sd, zoo_data = prices.zoo) original_sd_zoo <- zoo(original_time_sd, order.by = index(prices.zoo))
结果示例
比如查看rolling_sd_zoo的部分结果,你会看到:
# 2000-05-10 08:55:00 2000-05-10 09:00:00 2000-05-10 09:10:00 # NA 5.773503 10.000000
- 08:55的窗口内只有20这一个值,所以返回NA
- 09:00的窗口内有20和30,标准差是
sd(c(20,30))≈5.77 - 09:10的窗口内有20、30、40,标准差是
sd(c(20,30,40))=10,完全符合预期
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

