gpt4 book ai didi

r - 如何加快 R data.table 中缺失的搜索过程

转载 作者:行者123 更新时间:2023-12-04 10:49:37 28 4
gpt4 key购买 nike

我正在编写一个用于缺失值处理的通用函数。数据可以有字符、数字、因子和整数类型的列。数据示例如下

dt<-data.table(
num1=c(1,2,3,4,NA,5,NA,6),
num3=c(1,2,3,4,5,6,7,8),
int1=as.integer(c(NA,NA,102,105,NA,300,400,700)),
int3=as.integer(c(1,10,102,105,200,300,400,700)),
cha1=c('a','b','c',NA,NA,'c','d','e'),
cha3=c('xcda','b','c','miss','no','c','dfg','e'),
fact1=c('a','b','c',NA,NA,'c','d','e'),
fact3=c('ad','bd','cc','zz','yy','cc','dd','ed'),
allm=as.integer(c(NA,NA,NA,NA,NA,NA,NA,NA)),
miss=as.character(c("","",'c','miss','no','c','dfg','e')),
miss2=as.integer(c('','',3,4,5,6,7,8)),
miss3=as.factor(c(".",".",".","c","d","e","f","g")),
miss4=as.factor(c(NA,NA,'.','.','','','t1','t2')),
miss5=as.character(c(NA,NA,'.','.','','','t1','t2'))
)

我正在使用此代码来标记缺失值:
dt[,flag:=ifelse(is.na(miss5)|!nzchar(miss5),1,0)]

但结果很慢,另外我必须添加也可以考虑“。”的逻辑。作为失踪。
所以我打算写这个用于缺失值识别
dt[miss5 %in% c(NA,'','.'),flag:=1]

但是在 600 万的记录集上运行它需要接近 1 秒,而
dt[!nzchar(miss5),flag:=1]  takes close 0.14 secod to run.

我的问题是,我们可以有一个代码,其中花费的时间尽可能少,同时我们可以查找值 NA,blank 和 Dot(NA,".","") 作为缺失值吗?

任何帮助都受到高度赞赏。

最佳答案

==%in%优化为自动使用二进制搜索(新功能:自动索引)。要使用它,我们必须确保:

a) 我们使用 dt[...]而不是 set()因为它尚未在 set() 中实现, #1196 .

b) 当 RHS 到 %in%比 LHS 具有更高的 SEXPTYPE,自动索引重新路由到基础 R 以确保正确的结果(因为二分搜索总是强制 RHS)。所以对于整数列,我们需要确保我们只传入 NA而不是 ".""" .

使用@akrun 的数据,这里是代码和运行时间:

in_col = grep("^miss", names(dt), value=TRUE)
out_col = gsub("^miss", "flag", in_col)
system.time({
dt[, (out_col) := 0L]
for (j in seq_along(in_col)) {
if (class(.subset2(dt, in_col[j])) %in% c("character", "factor")) {
lookup = c("", ".", NA)
} else lookup = NA
expr = call("%in%", as.name(in_col[j]), lookup)
tt = dt[eval(expr), (out_col[j]) := 1L]
}
})
# user system elapsed
# 1.174 0.295 1.476

这个怎么运作:

a) 我们首先将所有输出列初始化为 0。

b) 然后,对于每一列,我们检查它的类型并创建 lookup因此。

c) 然后我们为 i 创建相应的表达式- miss(.) %in% lookup
d) 然后我们计算 i 中的表达式,它将使用自动索引非常快速地创建索引,并使用该索引使用二进制搜索快速找到匹配的索引。

Note: If necessary, you can add a set2key(dt, NULL) at the end of for-loop so that the created indices are removed immediately after use (to save space).



与这次运行相比,@akrun 的最快答案需要 6.33 秒,这是 ~4.2 倍的加速。

更新:在 400 万行和 100 列上,大约需要 9.2 秒。这是每列约 0.092 秒。

调用 [.data.table 100 次可能很贵。在 set() 中实现自动索引时,比较性能会很好。

关于r - 如何加快 R data.table 中缺失的搜索过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30997215/

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