如何向量化后续行的比较
How to vectorize comparison of subsequent rows
我正在尝试加快我当前针对以下问题的实施:
period
中订购的文章 articleID
的到达是通过其 leadtime
确定的,该时间因时期而异。我想确定次数,一件商品已经overtaken
,即晚点的商品比早点的商品早到。
我当前的实现(是的,两个丑陋的 for 循环):
library(data.table)
lt <- CJ(articleID=c("A", "B", "C"), period=1:100)
lt$leadtime <- round(runif(length(lt$period))*100,0)
lt[, arrival:=period+leadtime]
setkey(lt,articleID,period)
overtakenSum <- 0
for (art in unique(lt$articleID)) {
for (p in sort(unique(lt[art,period]))) {
# find subsequent period of item where arrival is before arrival period of article in current period
overtakenSum <- overtakenSum +
sum(lt[art==articleID & period>p,arrival] <
lt[.(art,p),arrival])
}
print(overtakenSum)
}
对于我需要考虑的文章数和期数,实施速度太慢。
有没有办法
- 矢量化这些操作(比如 diff 的一些高级用法)或
- 利用 data.table 中的特殊功能?
我不知道您如何才能避免问题的基本按行部分,因为每一行的各种总和似乎彼此之间没有关系。但是,通过简单地重写您的解决方案,我看到了大约 3 倍的加速:
lt[, {perArt = .SD; # renaming, to be able to run the next line correctly
perArt[, sum(perArt[period > p, arrival] < arrival), by = .(p = period)][, sum(V1)]}
, by = articleID][, cumsum(V1)]
#[1] 1450 2599 3760
我正在尝试加快我当前针对以下问题的实施:
period
中订购的文章 articleID
的到达是通过其 leadtime
确定的,该时间因时期而异。我想确定次数,一件商品已经overtaken
,即晚点的商品比早点的商品早到。
我当前的实现(是的,两个丑陋的 for 循环):
library(data.table)
lt <- CJ(articleID=c("A", "B", "C"), period=1:100)
lt$leadtime <- round(runif(length(lt$period))*100,0)
lt[, arrival:=period+leadtime]
setkey(lt,articleID,period)
overtakenSum <- 0
for (art in unique(lt$articleID)) {
for (p in sort(unique(lt[art,period]))) {
# find subsequent period of item where arrival is before arrival period of article in current period
overtakenSum <- overtakenSum +
sum(lt[art==articleID & period>p,arrival] <
lt[.(art,p),arrival])
}
print(overtakenSum)
}
对于我需要考虑的文章数和期数,实施速度太慢。
有没有办法
- 矢量化这些操作(比如 diff 的一些高级用法)或
- 利用 data.table 中的特殊功能?
我不知道您如何才能避免问题的基本按行部分,因为每一行的各种总和似乎彼此之间没有关系。但是,通过简单地重写您的解决方案,我看到了大约 3 倍的加速:
lt[, {perArt = .SD; # renaming, to be able to run the next line correctly
perArt[, sum(perArt[period > p, arrival] < arrival), by = .(p = period)][, sum(V1)]}
, by = articleID][, cumsum(V1)]
#[1] 1450 2599 3760