矢量化思维
Vectorize thinking
我遇到矢量化问题。假设我有一个向量 x <- c(0,0,1,0,1,1,0)
,我想要的是获取向量 (1,0,1,1)
,或者删除从第一个点到第一个非零点的所有 0 以及最后一个点的所有 0非零点到最后一个点。这在正常情况下很容易,但棘手的部分是我不能使用任何循环(for、while 等)。基本上,我必须"vectorize"整个算法。有人帮忙吗?
我想你可以试试这个,
感谢 @JacobH
评论,这样会更快。
x <- c(0,0,1,0,1,1,0)
zeros <- which(x > 0)
x[zeros[1]:tail(zeros, n = 1)]
输出
[1] 1 0 1 1
好吧,如果速度是一个问题,只需使用循环即可:
x <- rpois(1e8,1)
# Zihu Guo & JacobH's answer
system.time({zeros <- which(x > 0); x[zeros[1]:tail(zeros, n = 1)]})
# user system elapsed
# 1.46 0.42 1.89
# a slightly improved version of their answer
system.time({zeros <- which(!!x); x[zeros[1]:tail(zeros, n = 1)]})
# user system elapsed
# 1.21 0.42 1.64
system.time({
lo = 0L
lov = 0L
while (!lov){ lo = lo+1L ; lov = lov+x[lo] }
hi = length(x)+1L
hiv = 0L
while (!hiv){ hi = hi-1L ; hiv = hiv+x[hi] }
x[lo:hi]
})
# user system elapsed
# 0.62 0.07 0.71
除了速度之外,这很好,因为它不需要真正的 R 知识。使用 Rcpp
包可能会更快。
(如果整个向量都是零,这将永远不会终止。如果这很重要,可以进行小幅调整。如果向量 大部分 为零,则 which
方法更快。例如,考虑 x <- rep(0L,1e8); x[1e8/2] <- 1L
.)
我遇到矢量化问题。假设我有一个向量 x <- c(0,0,1,0,1,1,0)
,我想要的是获取向量 (1,0,1,1)
,或者删除从第一个点到第一个非零点的所有 0 以及最后一个点的所有 0非零点到最后一个点。这在正常情况下很容易,但棘手的部分是我不能使用任何循环(for、while 等)。基本上,我必须"vectorize"整个算法。有人帮忙吗?
我想你可以试试这个,
感谢 @JacobH
评论,这样会更快。
x <- c(0,0,1,0,1,1,0)
zeros <- which(x > 0)
x[zeros[1]:tail(zeros, n = 1)]
输出
[1] 1 0 1 1
好吧,如果速度是一个问题,只需使用循环即可:
x <- rpois(1e8,1)
# Zihu Guo & JacobH's answer
system.time({zeros <- which(x > 0); x[zeros[1]:tail(zeros, n = 1)]})
# user system elapsed
# 1.46 0.42 1.89
# a slightly improved version of their answer
system.time({zeros <- which(!!x); x[zeros[1]:tail(zeros, n = 1)]})
# user system elapsed
# 1.21 0.42 1.64
system.time({
lo = 0L
lov = 0L
while (!lov){ lo = lo+1L ; lov = lov+x[lo] }
hi = length(x)+1L
hiv = 0L
while (!hiv){ hi = hi-1L ; hiv = hiv+x[hi] }
x[lo:hi]
})
# user system elapsed
# 0.62 0.07 0.71
除了速度之外,这很好,因为它不需要真正的 R 知识。使用 Rcpp
包可能会更快。
(如果整个向量都是零,这将永远不会终止。如果这很重要,可以进行小幅调整。如果向量 大部分 为零,则 which
方法更快。例如,考虑 x <- rep(0L,1e8); x[1e8/2] <- 1L
.)