select 一行具有特定 ID 值的数据框的最快方法是什么?
What is the fastest way to select a row of a data frame with a specific ID value?
现在我正在使用
分析一些数据
row = dataset[dataset$id == id1,]
和
row = subset(dataset,id == id1)
其中所有 id 值都是整数。
但是,在处理较大的数据集时,我得到的结果慢得令人失望。有什么方法可以加快这项特定任务的速度吗?
使用data.table
,我们可以在一个列上设置键,该键按指定的列以递增顺序对数据进行物理重新排序,这样我们就可以使用二进制搜索来进行子集化。
library(data.table)
setkey(setDT(data1), id)[.(id1)]
或者,从 data.table 版本 1.9.4+ 开始,DT[x == .]
和 DT[x %in% .]
形式的子集都在内部进行了优化以自动创建索引,然后使用二分查找子集在连续运行中,速度非常快(参见下面的基准测试)。
setDT(data1)[id == id1] # internally optimised to generate index automatically
查看 this post 了解更多信息。
数据
set.seed(24)
data1 <- data.frame(id= sample(1:6, 25, replace=TRUE), val=rnorm(25))
id1 <- 5L
PS:setDT()
通过引用将 data.frame 转换为 data.table。
基准
set.seed(29)
dat2 <- data.frame(id= sample(1:100, 1e8, replace=TRUE), val=rnorm(1e8))
# data.frame subset in base R
system.time(dat2[dat2$id == id1,])
# user system elapsed
# 6.287 0.646 7.081
# base R like syntax on data.table; create index and subset using binary search
system.time(setDT(dat2)[id == id1])
# user system elapsed
# 0.646 0.232 0.889
# successive runs are incredibly fast!
# 0.037 0.002 0.039
# 0.040 0.002 0.042
# alternatively set key once
system.time(setkey(setDT(dat2), id))
# 2.908 0.499 3.440
# and use binary search explicitly
system.time(dat2[.(id1)])
# user system elapsed
# 0.009 0.002 0.012
下面是base([)和dplyr(filter)的比较:
set.seed(29)
dat2 <- data.frame(id= sample(1:6, 3e6, replace=TRUE), val=rnorm(3e6))
library(dplyr)
system.time(dplyr::filter(dat2, id==5))
user system elapsed
0.029 0.004 0.033
system.time(dat2[dat2$id==5,])
user system elapsed
0.236 0.012 0.248
现在我正在使用
分析一些数据row = dataset[dataset$id == id1,]
和
row = subset(dataset,id == id1)
其中所有 id 值都是整数。
但是,在处理较大的数据集时,我得到的结果慢得令人失望。有什么方法可以加快这项特定任务的速度吗?
使用data.table
,我们可以在一个列上设置键,该键按指定的列以递增顺序对数据进行物理重新排序,这样我们就可以使用二进制搜索来进行子集化。
library(data.table)
setkey(setDT(data1), id)[.(id1)]
或者,从 data.table 版本 1.9.4+ 开始,DT[x == .]
和 DT[x %in% .]
形式的子集都在内部进行了优化以自动创建索引,然后使用二分查找子集在连续运行中,速度非常快(参见下面的基准测试)。
setDT(data1)[id == id1] # internally optimised to generate index automatically
查看 this post 了解更多信息。
数据
set.seed(24)
data1 <- data.frame(id= sample(1:6, 25, replace=TRUE), val=rnorm(25))
id1 <- 5L
PS:setDT()
通过引用将 data.frame 转换为 data.table。
基准
set.seed(29)
dat2 <- data.frame(id= sample(1:100, 1e8, replace=TRUE), val=rnorm(1e8))
# data.frame subset in base R
system.time(dat2[dat2$id == id1,])
# user system elapsed
# 6.287 0.646 7.081
# base R like syntax on data.table; create index and subset using binary search
system.time(setDT(dat2)[id == id1])
# user system elapsed
# 0.646 0.232 0.889
# successive runs are incredibly fast!
# 0.037 0.002 0.039
# 0.040 0.002 0.042
# alternatively set key once
system.time(setkey(setDT(dat2), id))
# 2.908 0.499 3.440
# and use binary search explicitly
system.time(dat2[.(id1)])
# user system elapsed
# 0.009 0.002 0.012
下面是base([)和dplyr(filter)的比较:
set.seed(29)
dat2 <- data.frame(id= sample(1:6, 3e6, replace=TRUE), val=rnorm(3e6))
library(dplyr)
system.time(dplyr::filter(dat2, id==5))
user system elapsed
0.029 0.004 0.033
system.time(dat2[dat2$id==5,])
user system elapsed
0.236 0.012 0.248