关于数据表1.9.2中的GForce
我不知道如何在数据中充分利用GForce。表1.9.2 新优化:GForce。不分组数据,而是将组位置传递到sum和mean(gsum和gmean)的分组版本中,然后在一次连续传递列中计算所有组的结果,以提高缓存效率。此外,由于g*函数只调用一次,因此我们不需要找到方法来加快对每个组重复调用sum或mean的速度` 提交以下代码时关于数据表1.9.2中的GForce,r,data.table,R,Data.table,我不知道如何在数据中充分利用GForce。表1.9.2 新优化:GForce。不分组数据,而是将组位置传递到sum和mean(gsum和gmean)的分组版本中,然后在一次连续传递列中计算所有组的结果,以提高缓存效率。此外,由于g*函数只调用一次,因此我们不需要找到方法来加快对每个组重复调用sum或mean的速度` 提交以下代码时 DT <- data.table(A=c(NA,NA,1:3), B=c("a",NA,letters[1:3])) DT[,sum(A,na.rm=TRUE)
DT <- data.table(A=c(NA,NA,1:3), B=c("a",NA,letters[1:3]))
DT[,sum(A,na.rm=TRUE),by= B]
该结果是否解释了GForce所做的事情,添加了na.rm=TRUE/FALSE
选项
非常感谢 这与
na.rm
无关。你之前的表演也不错。不过,我明白你为什么会这么想。以下是同一条新闻的其余部分:
Examples where GForce applies now :
DT[,sum(x,na.rm=),by=...] # yes
DT[,list(sum(x,na.rm=),mean(y,na.rm=)),by=...] # yes
DT[,lapply(.SD,sum,na.rm=),by=...] # yes
DT[,list(sum(x),min(y)),by=...] # no. gmin not yet available
GForce is a level 2 optimization. To turn it off: options(datatable.optimize=1)
Reminder: to see the optimizations and other info, set verbose=TRUE
你不需要做任何有益的事情,这是一个自动优化
下面是一个关于5亿行和4列(13GB)的示例。首先创建并说明数据:
$ R
R version 3.0.2 (2013-09-25) -- "Frisbee Sailing"
Copyright (C) 2013 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)
> require(data.table)
Loading required package: data.table
data.table 1.9.2 For help type: help("data.table")
> DT = data.table( grp = sample(1e6,5e8,replace=TRUE),
a = rnorm(1e6),
b = rnorm(1e6),
c = rnorm(1e6))
> tables()
NAME NROW MB COLS KEY
[1,] DT 500,000,000 13352 grp,a,b,c
Total: 13,352MB
> print(DT)
grp a b c
1e+00: 695059 -1.4055192 1.587540028 1.7104991
2e+00: 915263 -0.8239298 -0.513575696 -0.3429516
3e+00: 139937 -0.2202024 0.971816721 1.0597421
4e+00: 651525 1.0026858 -1.157824780 0.3100616
5e+00: 438180 1.1074729 -2.513939427 0.8357155
---
5e+08: 705823 -1.4773420 0.004369457 -0.2867529
5e+08: 716694 -0.6826147 -0.357086020 -0.4044164
5e+08: 217509 0.4939808 -0.012797093 -1.1084564
5e+08: 501760 1.7081212 -1.772721799 -0.7119432
5e+08: 765653 -1.1141456 -1.569578263 0.4947304
现在是GForce optimization打开(默认设置)的时候了。注意这里没有设置键。这就是所谓的cold by或ad hoc by,当你想以多种不同的方式分组时,这是一种常见的做法
> system.time(ans1 <- DT[, lapply(.SD,sum), by=grp])
user system elapsed
47.520 5.651 53.173
> system.time(ans1 <- DT[, lapply(.SD,sum), by=grp])
user system elapsed
47.372 5.676 53.049 # immediate repeat to confirm timing
请注意,data.table
根据组首次出现的时间保留组的顺序。要对分组结果排序,请使用keyby=
而不是by=
要重新启用GForce优化(默认值为Inf
以从所有优化中获益):
旁白:如果您不熟悉lappy(.SD,…)
语法,这只是一种按组通过列应用函数的方法。例如,这两条线是等效的:
DT[, lapply(.SD,sum), by=grp] # (1)
DT[, list(sum(a),sum(b),sum(c)), by=grp] # (2) exactly the same
第一个(1)更有用,因为您有更多的列,特别是与.SDcols
结合使用,以控制要通过哪些列子集应用函数
这条新闻只是想传达这样一个信息:不管使用哪种语法,也不管你是否通过了na.rm
,GForce优化仍然会被应用。这意味着你可以在一个调用中混合使用sum()
和mean()
(语法(2)允许),但是一旦你做了其他事情(比如min()
),那么GForce就不会启动,因为min
还没有完成;当前只有mean
和sum
具有GForce优化。您可以使用verbose=TRUE
查看是否应用了GForce
用于此正时的机器的详细信息:
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 8
Core(s) per socket: 1
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 62
Stepping: 4
CPU MHz: 2494.022
BogoMIPS: 4988.04
Hypervisor vendor: Xen
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 25600K
NUMA node0 CPU(s): 0-7
> options(datatable.optimize=1)
> system.time(ans2 <- DT[, lapply(.SD,sum), by=grp])
user system elapsed
97.274 3.383 100.659
> system.time(ans2 <- DT[, lapply(.SD,sum), by=grp])
user system elapsed
97.199 3.423 100.624 # immediate repeat to confirm timing
> identical(ans1,ans2)
[1] TRUE
> print(ans1)
grp a b c
1: 695059 16.791281 13.269647 -10.663118
2: 915263 43.312584 -33.587933 4.490842
3: 139937 3.967393 -10.386636 -3.766019
4: 651525 -4.152362 9.339594 7.740136
5: 438180 4.725874 26.328877 9.063309
---
999996: 372601 -2.087248 -19.936420 21.172860
999997: 13912 18.414226 -1.744378 -7.951381
999998: 150074 -4.031619 8.433173 -22.041731
999999: 385718 11.527876 6.807802 7.405016
1000000: 906246 -13.857315 -23.702011 6.605254
> options(datatable.optimize=Inf)
DT[, lapply(.SD,sum), by=grp] # (1)
DT[, list(sum(a),sum(b),sum(c)), by=grp] # (2) exactly the same
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 8
Core(s) per socket: 1
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 62
Stepping: 4
CPU MHz: 2494.022
BogoMIPS: 4988.04
Hypervisor vendor: Xen
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 25600K
NUMA node0 CPU(s): 0-7