【问题标题】:data.table time subset vs xts time subsetdata.table 时间子集与 xts 时间子集
【发布时间】:2013-06-25 02:52:38
【问题描述】:

您好,我希望按时间对一些分钟数据进行子集化。我通常使用xts 做类似的事情:

subset.string <- 'T10:00/T13:00' 
xts.min.obj[subset.string]

获取每天上午 10 点到下午 1 点(含)之间的所有行,并以 xts 格式输出。但是对于我的目的来说有点慢......例如

j <- xts(rnorm(10e6),Sys.time()-(10e6:1))
system.time(j['T10:00/T16:00'])
   user  system elapsed 
  5.704   0.577  17.115 

我知道data.table 速度很快,并且可以对大型数据集进行子集化,所以我想知道是否与fasttime 包一起处理快速 POSIXct 创建,是否值得创建类似的函数

dt.time.subset <- function(xts.min.obj, subset.string){
  require(data.table)
  require(fasttime)
  x.dt <- data.table(ts=format(index(xts.min.obj),"%Y-%m-%d %H:%M:%S %Z"),
                     coredata(xts.min.obj))
  out <- x.dt[,some.subsetting.operation.using."%between%"]
  xts(out,fastPOSIXct(out[,ts])
}

要将 xts.min.obj 转换为 data.table 添加某种字符索引,然后使用 data.table 对相关行进行子集化,使用带有 fasttime 的输出行索引重新创建 xts 输出?或者对于已经高度优化和用 C 编写的东西,这是否是过多的多余操作?

【问题讨论】:

  • 抱歉,您的问题是什么?你知道%between% 那么你还想要什么?
  • 首先不太清楚如何使用 %between% 和时间,目前我正在将索引转换为字符串而不是使用 POSIXct,因为我的印象是POSIXct 很慢...另外我认为它不是每天都有效...
  • 每天的部分都可以通过 format(..., "%H:%M") %between% c("10:00", "13:00") 来解决,但我仍然不确定为什么您需要 data.table 来进行 just 子集化 - 我非常怀疑它是否有用返回在xtsdata.table 之间来回切换,如果你的唯一目的是子集(但你总是可以给我们一些你的操作很慢的示例数据)
  • 已添加虚拟示例数据...

标签: r benchmarking data.table xts


【解决方案1】:

如果您可以在UTC 中指定您的范围,您可以这样做:

j[(.index(j) %% 86400) %between% c(10*3600, 16*3600 + 60)]
# +60 because xts includes that minute; you'll need to offset the times
# appropriately to match with xts unless you live in UTC :)

j <- xts(rnorm(10e6),Sys.time()-(10e6:1))
system.time(j[(.index(j) %% 86400) %between% c(10*3600, 16*3600 + 60)])
#  user  system elapsed 
#  1.17    0.08    1.25 
# likely faster on your machine as mine takes minutes to run the OP bench

【讨论】:

  • 使用.index直接访问数字索引。
  • 我没有意识到你可以在data.table之外使用%between%,如果原始对象不是UTC,最好先转换索引,然后转换子集时间。 .. 即如果寻找上午 10 点到下午 4 点之间的子集,它引用了在柏林设置了时区的原始 xts 对象,那么我会将它们转换为上午 10 点到 UTC,对吗?即世界标准时间上午 8 点?然后使用您的方法实际子集,最后重新转换回原始时区?
  • @h.l.m 我认为时区转换在计算上会非常昂贵,如果可以的话我会避免它
  • 如果我不应该将索引时区转换为 UTC,您将如何调整 %between% c(10*3600, 16*3600 + 60) 部分以处理时区?因为我的努力似乎没有奏效......
  • 比较index(j)[1]as.POSIXlt(index(j)[1], tz = "UTC") 看看有什么不同;就我而言,它是“09:00 CDT”和“14:00 UCT”,所以要进行“T10:00/T16:00”比较,我必须将这些数字调整为c((10+5)*3600, (16+6)*3600 + 60)。注意夏令时。
猜你喜欢
  • 2014-07-16
  • 2012-12-04
  • 1970-01-01
  • 2017-12-03
  • 2017-12-01
  • 1970-01-01
  • 2017-07-27
  • 2014-03-11
  • 1970-01-01
相关资源
最近更新 更多