【发布时间】:2018-12-02 12:52:52
【问题描述】:
我有这样的数据:
library(data.table)
NN = 10000000
set.seed(32040)
DT <- data.table(
col = 1:10000000,
timestamp = 1521872652 + sample(7000001, NN, replace = TRUE)
)
我正在尝试将唯一的年份和星期提取为代码,以便对重复项进行排序(真实数据表具有 userID 以及更多内容)。我有一个有效的当前解决方案(如下),但是在从日期列中唯一地粘贴几周和年份的部分上它很慢。使用anytime 包创建日期并从lubridate 中提取week 和year 仍然非常快。有人可以帮我加快速度吗?谢谢!
我的慢代码(有效,但我想加快速度):
library(anytime)
library(lubridate)
tz<-"Africa/Addis_Ababa"
DT$localtime<- anytime(DT$timestamp, tz=tz) ###Lightning fast
DT$weekuni <- paste(year(DT$localtime),week(DT$localtime),sep="") ###super slow
我的测试表明是 paste 杀死了我:
非常快的anytime 转换到日期:
system.time(DT$localtime<- anytime(DT$timestamp, tz=tz)) ###Lightning fast
user system elapsed
0.264 0.417 0.933
lubridate 周和年从日期的快速转换,但慢 paste:
> system.time(DT$weekuni1 <- week(DT$localtime)) ###super slow
user system elapsed
1.203 0.188 1.400
> system.time(DT$weekuni2 <- year(DT$localtime))
user system elapsed
1.229 0.189 1.427
> system.time(DT$weekuni <- paste0(DT$weekuni1,dt$weekuni2))
user system elapsed
14.652 0.344 15.483
【问题讨论】:
-
pkg:data.table 中已经有一个
year和week函数。如果效率是一个问题,覆盖那些似乎是不明智的。并且函数拼写为paste,但这种用法与[paste]标签定义不一致。我原以为使用 data.table 中的:=函数将是可行的方法,而不是使用$.data.frame -
你的建议有点快,但仍然比我认为的要慢,因为时间列来自任何时间:
> system.time(dt <- dt[,weekuni:=paste0(year(dt$localtime),week(dt$localtime)),]) user system elapsed 6.285 0.412 6.739 -
好吧,您正在制作两个额外的向量,然后在附加它们之前将它们强制转换为字符。我不知道为什么这应该是闪电般的速度。
-
您应该注意加载包时出现的屏蔽消息。
-
润滑年/周函数可能会更快。我们依赖 POSIXlt 转换,这可能很慢。
标签: r performance time data.table