评估data.table的大小比data.frame快

chr*_*oss 10 r data.table

有人可以帮我评估使用data.table的数据框的大小,搜索速度更快吗?在我的用例中,数据框将是24,000行和560,000行.总共挑出40行的块以供进一步使用.

示例:DF是一个包含120行,7列(x1到x7)的数据帧; "string"占据x1的前40行.

DF2是DF => 120,000行的1000倍

对于DF data.table的大小较慢,对于DF2的大小,它更快.

码:

> DT <- data.table(DF)
> setkey(DT, x1)
> 
> DT2 <- data.table(DF2)
> setkey(DT2, x1)
> 
> microbenchmark(DF[DF$x1=="string", ], unit="us")
Unit: microseconds
                    expr     min       lq   median       uq     max neval
 DF[DF$x1 == "string", ] 282.578 290.8895 297.0005 304.5785 2394.09   100
> microbenchmark(DT[.("string")], unit="us")
Unit: microseconds
            expr      min       lq  median      uq      max neval
 DT[.("string")] 1473.512 1500.889 1536.09 1709.89 6727.113   100
> 
> 
> microbenchmark(DF2[DF2$x1=="string", ], unit="us")
Unit: microseconds
                      expr     min       lq   median       uq      max neval
 DF2[DF2$x1 == "string", ] 31090.4 34694.74 35537.58 36567.18 61230.41   100
> microbenchmark(DT2[.("string")], unit="us")
Unit: microseconds
             expr      min       lq   median       uq      max neval
 DT2[.("string")] 1327.334 1350.801 1391.134 1457.378 8440.668   100
Run Code Online (Sandbox Code Playgroud)

Rol*_*and 16

library(microbenchmark)
library(data.table)
timings <- sapply(1:10, function(n) {
  DF <- data.frame(id=rep(as.character(seq_len(2^n)), each=40), val=rnorm(40*2^n), stringsAsFactors=FALSE)
  DT <- data.table(DF, key="id")     
  tofind <- unique(DF$id)[n-1]
  print(microbenchmark( DF[DF$id==tofind,],
                        DT[DT$id==tofind,],
                        DT[id==tofind],
                        `[.data.frame`(DT,DT$id==tofind,),
                        DT[tofind]), unit="ns")$median
})

matplot(1:10, log10(t(timings)), type="l", xlab="log2(n)", ylab="log10(median (ns))", lty=1)
legend("topleft", legend=c("DF[DF$id == tofind, ]",
                           "DT[DT$id == tofind, ]",
                           "DT[id == tofind]",
                           "`[.data.frame`(DT,DT$id==tofind,)",
                           "DT[tofind]"),
       col=1:5, lty=1)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

2016年1月:更新至 data.table_1.9.7

data.table自写完以来已经做了一些更新(增加[.data.table了一些开销,因为内置了一些参数/健壮性检查,但也引入了自动索引).这是GitHub的2016年1月13日版1.9.7的更新版本:

jan_2016

主要的创新是第三种选择现在利用自动索引.主要结论仍然是相同的 - 如果你的桌子是任何非平凡的大小(大约500个观察),data.table帧内呼叫更快.

(有关更新的剧情说明:一些小的事情(未记录y轴,以微秒表示,更改x轴标签,添加标题),但一个不平凡的事情是我更新了microbenchmarks到增加一些稳定性在估计中 - 即,我将times论证设定为as.integer(1e5/2^n))

  • @chriscross是的,我认为这是外卖,虽然我认为data.tables也是出于其他原因(更好的语法,其他快速的操作,......),所以我说你放弃香草是安全的data.frames.(顺便说一句,data.tables只是一种特殊类型的data.frame;这就是为什么`\`[.data.frame \``对它们起作用.) (2认同)
  • @MichaelChirico和Roland:很有意思.+1.在这里发推文:https://twitter.com/MattDowle/status/687397266513072129 (2认同)