data.table 索引 (setkey) 中的列顺序是否重要?
Does order of columns matter in data.table indexing (setkey)?
我对索引 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
的参数,它被传递给 ...
并被忽略(感谢@ak运行 指出这一点)。从中得到你想要的东西的最好方法可能是 运行 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]
}
这是每个 ar运行gement 重复 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
从这个简单的例子来看,您最好的选择是:不要键入 table(预排序的收益似乎很小),或者先键入 (A,B)
然后离开它。
反向——先按 (B,A)
键然后离开——也表现得很好。鉴于此,我真的很惊讶 XBA
的表现如此糟糕。
如果你想知道为什么它似乎没有键控那么快,它基本上是所有键控所做的,对于你想要做的,是预排序数据;这只会在给定操作中最低限度地提高速度,但必须在操作之间重新输入密钥是一种成本。按照手册的说法,这是 keyed by 与 ad 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 非常令人满意。
我对索引 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
的参数,它被传递给 ...
并被忽略(感谢@ak运行 指出这一点)。从中得到你想要的东西的最好方法可能是 运行 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]
}
这是每个 ar运行gement 重复 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
从这个简单的例子来看,您最好的选择是:不要键入 table(预排序的收益似乎很小),或者先键入 (A,B)
然后离开它。
反向——先按 (B,A)
键然后离开——也表现得很好。鉴于此,我真的很惊讶 XBA
的表现如此糟糕。
如果你想知道为什么它似乎没有键控那么快,它基本上是所有键控所做的,对于你想要做的,是预排序数据;这只会在给定操作中最低限度地提高速度,但必须在操作之间重新输入密钥是一种成本。按照手册的说法,这是 keyed by 与 ad hoc by:
相比When
by
contains the first n columns ofx
'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 withkeyby
= defined below.
键控的真正速度优势在于子集和合并——对于像您这样的操作,我发现 ad hoc bys 非常令人满意。