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

如何用1小时滚动窗口计算非规则时间序列的标准差?含zoo实操需求

非规则时间序列的1小时滚动窗口标准差计算(base R + zoo实现)

我来帮你解决这个非规则时间序列的滚动标准差计算问题!针对你提出的「每5分钟计算一次过去1小时内px的标准差」需求,我们可以用base R结合zoo包来实现,逻辑清晰且完全符合你的偏好,一步步来:

核心思路

因为你的原始数据是非规则时间序列,不能直接用基于观测数量的滚动窗口函数(比如rollapply默认的窗口),我们需要:

  1. 生成你要求的「每5分钟」的规则时间序列,作为计算的时间节点
  2. 对每个时间节点,筛选出过去1小时范围内的所有原始数据
  3. 计算这些数据的标准差(注意处理样本量不足的情况)

具体代码实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:48:03