【问题标题】:Moving Maximum in last 5 minutes in RR中最后5分钟的移动最大值
【发布时间】:2014-03-28 01:05:15
【问题描述】:

我想知道如何在 R 中以 O(n) 时间在最后 5 分钟内实现价格的移动最大值和最小值。我的数据由两列组成:一列以秒为单位,另一列以秒为单位价格。现在,我取当前时间,减去 5 分钟,最后 5 分钟的子集,然后在每个索引处搜索 min 和 max,所以操作是 O(n^2)。有没有办法在 O(n) 中做到这一点?

样本数据:

时间 [34200.19, 34200.23, 34201.45, ..., 35800, 35800.2, 35800.5]

价格 [100, 103, 102, ..., 95, 97, 99]

【问题讨论】:

  • 如果过去 5 分钟的平均事件数保持不变,从技术上讲不是 O(n^2) 而是 O(n)。
  • 好吧,在每个索引处,我都在执行 O(n) 搜索最大值和最小值,所以对于整个数据集,那不是 O(n^2) 吗?跨度>
  • 搜索最大值仅为 O(1)。你可以说 O(5)...
  • 哦,我的示例数据具有误导性,每分钟有很多事务,我只是不想让它过于混乱。

标签: r time max min


【解决方案1】:

下面将直接方法与稍微更有效的变体进行比较,但它看起来在我尝试使用 (10,000 - 100,000) 的值上缩放为大约 n^1.6 - 部分取决于是否假设增加 n同一时间段内的点数更多,或延长的时间段更长。

#Create some data 
n <- 10000
d <- data.frame(t=as.POSIXct(24*3600*runif(n), origin = "2014-01-01"),x=runif(n))
d <- d[order(d$t),]

d$inmax2 <-d$inmax <- rep(FALSE,n)
d$inmax2[1] <-d$inmax[1] <- TRUE

if (max(diff(d$t)) > 300) warning("There are gaps of more than 300 secs")

#Method 1, assume that you've done something like this
t1 <- system.time({
  for (i in 2:n) d$inmax[i] <- !any((difftime(d$t[i], d$t[1:(i-1)] ,units="secs") < 300) & (d$x[i] < d$x[1:(i-1)] ))
})

#Method 2    
t2 <- system.time({
cand <- 1
next_cand <- 2

while (next_cand <= n)
{
  cand <- cand[difftime(d$t[next_cand],d$t[cand],units="secs")<300]
  cand <- c(cand[d$x[cand] > d$x[next_cand]],next_cand)
  if(length(cand)==1) d$inmax2[cand] <- TRUE
  next_cand <- next_cand + 1

}

})

rbind(method1=t1,method2=t2)
#         user.self sys.self elapsed user.child sys.child
# method1     14.98     0.03   15.04         NA        NA
# method2      2.59     0.05    2.63         NA        NA
all(d[[3]]==d[[4]])
# TRUE

方法是通过保留过去 5 分钟内所有可能的候选人不少于当前候选人。如果没有这样的候选人,则当前必须是最大值。我假设你可以概括到最低限度。

如果您想知道数据点之间最后 5 分钟内的最大值而不是数据点的最大值,则可能不起作用 - 不确定您是否需要这样做

【讨论】:

    【解决方案2】:

    首先按时间对数据帧进行排序。然后保持价格的最大堆,在每个班次后删除丢失的价格条目。因为重新平衡堆是O(log n),所以这将是O(n log n)。要实现最大堆,请查阅任何算法教科书(尽管稍后我可能会编辑这篇文章)。

    【讨论】:

    • 谢谢!我知道它可以在 O(n log n) 时间内完成,但我也读到它可以在 O(n) 时间内完成,两个堆栈代表一个队列。你知道R中是否有实现吗?
    猜你喜欢
    • 1970-01-01
    • 2021-02-21
    • 2019-08-29
    • 2021-10-28
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 2016-08-31
    • 2014-05-09
    相关资源
    最近更新 更多