我正在使用数据。快速子集表。然而,当我的子集不是基于等于某个值的键,而是小于某个值时,它会花费很多时间。例如:
DT["2"]
速度快,而
DT[key<2]
是缓慢的。
我假设第一个是二进制搜索,第二个是矢量扫描,但如何以快速的方式做第二个?
通常,当您对键列进行子集以利用基于快速二进制搜索的子集时,您会这样做:
DT[J(values)] # assuming subset here is on the first key column.
# (or)
DT[.(values)] # idem
这里的.
和J
完全相同。当键列为character
类型时,由于还必须引用字符值,因此为了方便起见,如果可能的话,data.table
也允许不使用J
或.
进行连接。也就是说,
DT["a"] # subset on the first key column if one exists
# (or)
DT[J("a")] # idem
# (or)
DT[.("a")] # idem
此功能仅用于字符向量。这是可能的,因为您不能以任何其他方式在i
中使用字符向量来子集data.table
。所以,很容易看出你想加入。但是,如果您提供DT[2]
, 2
在这里是numeric
, data.table
无法真正告诉您是期望连接还是正常行子集。这就是为什么它只用于字符。
现在,DT[J(.)]
将是快速的,因为当键被设置时,它已经排序了,因此我们可以使用快速二叉搜索来子集。然而,DT[x < .]
使用正常矢量扫描方法。也就是说,它将检查x
的所有值以获取a
的值,即使这些值是按x
排序的。因此,第二个将比第一个慢。
有一些特性请求来启用基于范围子集的二进制搜索。你可以看看这里。一旦实现,这些东西会自动变得更快。我们还没开始呢。
HTH .
PS:请注意,您正在比较DT["2"]
-这是一个基于字符键列的二进制搜索子集与DT[key < 2]
,其中key
在这里是数字。它们不一样。等价的(如上所述)是DT[J(2)]
。
还要注意它们不是等价操作。DT[J(2)]
只查找DT中与2
匹配的键列,而DT[key < 2]
查找[min[key], 2)
范围内的所有值。