【发布时间】:2020-06-03 02:17:42
【问题描述】:
目前我有以下 data.table :
item city dummyvar
A Austin 1
A Austin 1
A Austin 100
B Austin 2
B Austin 2
B Austin 200
A NY 1
A NY 1
A NY 100
B NY 2
B NY 2
B NY 200
我有一个名为ImbalancePoints 的用户定义函数,它应用于dummyvar,它返回检测到dummyvar 突然变化的行。我这样做的方式如下:
my.data.table[,
.(item, city , imb.points = list(unique(try(ImbalancePoints(dummyvar), silent = T))) ),
by = .(city, item)
]
对于NY 的情况,假设我得到了一个data.table 对象,如下所示:
item city imb.points
A NY 3,449
其中imb.points 列是具有嵌套列表作为其元素的列,对于此示例,数字 3 和 449 表示对于 city = NY 和 item = A 的情况发生突然变化的行。然而,我面临的问题是我有大约。 12个不同城市的3000个不同的项目,计算这个需要很长时间。我想知道您是否可以告诉我如何矢量化/加速这个计算,因为我上次尝试这个花了将近 2 个小时但没有完成。
我不知道它是否有任何帮助,但我也附上了ImbalancePoints 函数:
library(pracma)
ImbalancePr <- function(eval.column) {
n <- length(eval.column)
imbalance <- rep(0, n)
b_t = rep(0,n)
elem_diff <- diff(eval.column)
for(i in 2:n)
{
imbalance[i] <- sign(elem_diff[i-1]) * (elem_diff[i-1] != 0)
+ imbalance[i-1]*(elem_diff[i-1] == 0)
}
return(imbalance)
}
ImbalancePoints <- function(eval.column, w0 = 100, bkw_T = 10, bkw_b = 10){
bv_t <- ImbalancePr(eval.column)
w0 <- min(min(which(cumsum(bv_t) != 0)), w0)
Tstar <- w0
E0t <- Tstar
repeat{
Tlast <- sum(Tstar)
nbt <- min(bkw_b, Tlast-1)
P <- pracma::movavg(bv_t[1:Tlast], n = nbt, type = "e")
P <- tail(P,1)
bv_t_expected <- E0t * abs(P)
bv_t_cumsum <- abs(cumsum(bv_t[-(1:Tlast)]))
if(max(bv_t_cumsum) < bv_t_expected){break}else{
Tnew <- min(which(bv_t_cumsum >= bv_t_expected))
}
Tlast <- Tlast + Tnew
if(Tlast > length(eval.column)[1]){break}else{
Tstar <- c(Tstar,Tnew)
if(length(Tstar) <= 2){
E0t <- mean(Tstar)
}else{
nt <- min(bkw_T,length(Tstar)-1)
E0t <- pracma::movavg(Tstar[1:length(Tstar)], n = nt, type = "e")
E0t <- tail(E0t,1)
}
}
}
return(sort(unique(Tstar)))
}
编辑:感谢 Paul 的洞察力,我的问题只是矢量化 ImbalancePoints 函数内的重复循环。但是,我不是很精通编码,也没有看到直接的解决方案。如果有人可以给我一个建议,或者如果您知道辅助功能/库,我将不胜感激。
【问题讨论】:
-
能否用文字解释一下imbal点是如何定义的?
-
查看代码中的循环数,我可以看到这可能很慢。您为数据中的每一行调用
ImbalancePoints。这至少是城市数量的 3000 倍。所以这等于 36,000 次。每次调用此函数时,您都会调用ImbalancePr。此函数在列中循环 n 次。然后计算出 36,000*36,000 = 1,296,000,000 个循环。难怪。您的重复循环会使情况变得更糟。 -
@chinsoon12 可能不需要过多地输入数学细节,它会执行指数加权平均,当该平均值超过阈值时,它会检测到不平衡的点
标签: r data.table vectorization moving-average