gpt4 book ai didi

r - 为什么 DT1[DT2][, value1-value] 在列较少的 data.table 上比 DT1[DT2, value1-value] 快?

转载 作者:行者123 更新时间:2023-12-04 09:18:25 26 4
gpt4 key购买 nike

这与这个问题( Can I access repeated column names in `j` in a data.table join? )有关,之所以问这个问题是因为我认为与此相反的是真的。

data.table 只有 2 列:

假设你想加入两个 data.tables然后对两个连接的列执行一个简单的操作,这可以通过一次或两次调用 .[ 来完成。 :

N = 1000000
DT1 = data.table(name = 1:N, value = rnorm(N))
DT2 = data.table(name = 1:N, value1 = rnorm(N))
setkey(DT1, name)

system.time({x = DT1[DT2, value1 - value]}) # One Step

system.time({x = DT1[DT2][, value1 - value]}) # Two Step

原来打了两个电话 - 先做连接,然后做减法 - 明显比一次性快 .
> system.time({x = DT1[DT2, value1 - value]})
user system elapsed
0.67 0.00 0.67
> system.time({x = DT1[DT2][, value1 - value]})
user system elapsed
0.14 0.01 0.16

为什么是这样?

具有许多列的数据表:

如果您将很多列放入 data.table那么你最终会发现一步法更快 - 大概是因为 data.table仅使用您在 j 中引用的列.
N = 1000000
DT1 = data.table(name = 1:N, value = rnorm(N))[, (letters) := pi][, (LETTERS) := pi][, (month.abb) := pi]
DT2 = data.table(name = 1:N, value1 = rnorm(N))[, (letters) := pi][, (LETTERS) := pi][, (month.abb) := pi]
setkey(DT1, name)
system.time({x = DT1[DT2, value1 - value]})
system.time({x = DT1[DT2][, value1 - value]})

> system.time({x = DT1[DT2, value1 - value]})
user system elapsed
0.89 0.02 0.90
> system.time({x = DT1[DT2][, value1 - value]})
user system elapsed
1.64 0.16 1.81

最佳答案

我认为这是由于重复子集DT1[DT2, value1-value]为每个 nameDT2 .也就是说,您必须执行 j每个操作i在这里,而不是只有一个 j操作后join .对于 1e6 唯一条目,这变得非常昂贵。即,[.data.table变得重要和引人注目。

DT1[DT2][, value1-value] # similar to rowSums
DT1[DT2, value1-value]

在第一种情况下, DT1[DT2] ,您执行 join首先,它真的很快。当然,正如您所展示的,随着列数的增加,您会看到不同之处。但重点是执行一次连接。但在第二种情况下,您将按 DT2 的名称对 DT1 进行分组,并且您正在计算其中的每一个的差异。也就是说,您正在对 DT1 进行子集化对于 DT2 的每个值- 每个子集一个 'j' 操作!你可以通过运行这个来更好地看到这一点:
Rprof()
t1 <- DT1[DT2, value1-value]
Rprof(NULL)
summaryRprof()

# $by.self
# self.time self.pct total.time total.pct
# "[.data.table" 0.96 97.96 0.98 100.00
# "-" 0.02 2.04 0.02 2.04

Rprof()
t2 <- DT1[DT2][, value1-value]
Rprof(NULL)
summaryRprof()

# $by.self
# self.time self.pct total.time total.pct
# "[.data.table" 0.22 84.62 0.26 100.00
# "-" 0.02 7.69 0.02 7.69
# "is.unsorted" 0.02 7.69 0.02 7.69

当您有太多列和 join 时,重复子集的这种开销似乎可以克服。在许多列上超车作为耗时的操作。您可能可以通过分析其他代码自己检查一下。

关于r - 为什么 DT1[DT2][, value1-value] 在列较少的 data.table 上比 DT1[DT2, value1-value] 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17719480/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com