gpt4 book ai didi

r - 列的顺序在 data.table 索引(setkey)中重要吗?

转载 作者:行者123 更新时间:2023-12-02 01:36:01 28 4
gpt4 key购买 nike

我有一个关于索引 data.table 对象的问题。

setkey(data, A, B)
data[, C:=length(unique(B, na.rm=T)), by=A]

我想知道我是否应该将索引的顺序更改为

setkey(data, B, A)

提高速度。或者他们是一样的?我应该如何索引

data[c>=3, D:=sum(A), by=B]

最佳答案

首先,您的 length(unique(B, na.rm = T)) 位没有按照您认为的那样运行 --na.rm = TRUE不是 unique 的参数,它被传递给 ... 并被忽略(感谢@akrun 指出这一点)。从中得到你想要的东西的最好方法可能是运行 uniqueN(na.omit(B))

考虑到这一点,我运行了 9 (=3x3) 个基准测试,比较了您建议的代码(稍微加强版)的速度,改变了键控顺序:(B,A)(A,B) 或什么都没有 (X)。例如,下面提到的 BAX 函数是:

BAX <- function(){
data <- data.table(A = sample(50, size = 1e6, T),
B = sample(c(1:150000, NA), size = 1e6, T))
setkey(data, B, A)
data[ , C := uniqueN(na.omit(B)), by = A]
data[C >= 18500, D := sum(A), by = B]
}

这是每个排列重复 200 次的结果:

> microbenchmark(times = 200L,
XX(), XAB(), XBA(), ABX(), ABAB(),
ABBA(), BAX(), BAAB(), BABA())
Unit: milliseconds
expr min lq mean median uq max neval cld
XX() 70.05867 73.66665 105.2628 96.55443 116.5883 213.2926 200 a
XAB() 112.52981 121.91760 161.2687 157.66455 172.6626 370.4791 200 ef
XBA() 112.56648 122.65417 165.9513 158.96873 174.6038 406.3392 200 f
ABX() 79.59582 82.33355 110.8462 101.04939 125.0158 198.1082 200 a
ABAB() 83.81686 90.40803 123.1391 126.94853 132.0878 182.0694 200 b
ABBA() 112.50687 117.68602 151.8467 155.72603 161.2123 228.5776 200 de
BAX() 85.82144 93.87965 134.5259 130.40824 146.1559 263.9083 200 bc
BAAB() 100.48214 105.35192 150.9692 146.76173 156.0230 392.4626 200 de
BABA() 93.29706 104.70251 142.8426 138.12848 149.1106 279.4645 200 cd

从这个简单的例子来看,您最好的选择是:不要对表进行键控(预排序的 yield 似乎微乎其微),或者首先通过 (A,B) 进行键控并留下它。

反向操作——先按 (B,A) 键然后离开——也执行得很好。鉴于此,我真的很惊讶 XBA 的表现如此糟糕。


如果您想知道为什么它在没有键控的情况下看起来如此之快,基本上所有键控所做的,对于您想要做的,都是对数据进行预排序;这只会在给定操作中最低限度地提高速度,但必须在操作之间重新输入 key 是一种成本。按照手册的说法,这是一个keyed byad hoc by 相比:

When by contains the first n columns of x's key, we call this a keyed by. In a keyed by the groups appear contiguously in RAM and memory is copied in bulk internally, for extra speed. Otherwise, we call it an ad hoc by. Ad hoc by is still many times faster than tapply, for example, but just not as fast as keyed by when datasets are very large, in particular when the size of each group is large. Not to be confused with keyby= defined below.

键控的真正速度优势在于子集和合并——对于像您这样的操作,我发现 ad hoc bys 非常令人满意。

关于r - 列的顺序在 data.table 索引(setkey)中重要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31230217/

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