【发布时间】:2017-06-11 10:11:45
【问题描述】:
对于如何提高以下使用“某种”双滚动窗口耗尽我所有内存的代码示例的效率,有人有什么想法或建议吗?
首先,我通过一个简单的示例来定义问题,在这篇文章的底部有一个完整的 MWE(实现)。
首先,考虑以下“随机”测试向量(通常长度 >25000):
A <- c(1.23,5.44,6.3,8.45,NaN,3.663,2.63,1.32,6.623,234.6,252.36)
A 被分割成“种类”的训练和测试集,都带有滚动窗口。在这个 MWE 中,考虑了长度为 4 的训练集起点和长度为 2 的测试集长度(通常长度 >200)。所以最初,以下值是训练集和测试集的一部分:
train_1 <- A[1:4]
test_1 <- A[5:6]
接下来,我想在train_1(因此是第一个滚动窗口)的每个可能连续位置从train_1 中减去test_1,生成run_1_sub 矩阵。
run_1_sub <- matrix(NaN,3,2)
run_1_sub[1,] <- train_1[1:2] - test_1
run_1_sub[2,] <- train_1[2:3] - test_1
run_1_sub[3,] <- train_1[3:4] - test_1
之后,我想在run_1_sub 的每一行上找到每一行的总和除以每行中不是NaN 的条目数。
run_1_sum <-
sapply(1:3, function(x) {
sum(run_1_sub[x,], na.rm = T) / sum(!is.na(run_1_sub[x,]))
})
在下一步中,“种类”的训练和测试集通过将它们从 A 的顺序增加一来更新(因此是第二个滚动窗口):
train_2 <- A[2:5]
test_2 <- A[6:7]
如前所述,test_2 在train_2 中的每个可能位置减去run_2_sub 和run_2_sum。这个过程一直持续到测试集代表 A 的最后两个值,最后我以 6 个run_sum 矩阵结束(在这个 MWE 中)。但是,我的实现非常缓慢,我想知道是否有人可以帮助我提高它的效率?
这是我的实现:
# Initialization
library(zoo)
#rm(list = ls())
A <- c(1.23, 5.44, 6.3, 8.45, NaN, 3.663, 2.63, 1.32, 6.623, 234.6, 252.36) # test vector
train.length <- 4
test.length <- 2
run.length <- length(A) - train.length - test.length + 1
# Form test sets
test.sets <- sapply(1:run.length, function(x) {
A[(train.length + x):(train.length + test.length + x - 1)]
})
# Generate run_sub_matrices
run_matrix <- lapply(1:run.length, function(x) {
rollapply(A[x:(train.length + x - 1)], width = test.length, by = 1,
function(y) {
y - test.sets[, x]
})
})
# Genereate run_sum_matrices
run_sum <- sapply(1:length(run_matrix), function(x) {
rowSums(run_matrix[[x]], na.rm = T) / apply(run_matrix[[x]], 1, function(y) {
sum(!is.na(y))})
})
当然,以下初始化设置会显着减慢 run_sum 和 run_sub 的生成速度:
A <- runif(25000)*400
train.length <- 400
test.length <- 200
这里,生成run_sub的时间分别为120.04s和run_sum 28.69s。
关于如何提高和改进速度和代码的任何建议?
【问题讨论】:
标签: r performance optimization zoo rollapply