簡體   English   中英

大型 data.table 基准測試的逐行累積產品

[英]Row-wise cumulative product on large data.table benchmarking

假設我有一個大的 data.table,大約有 1000 列和 100,000 行,如下所示:

dt <- data.table(col1 = runif(10^4))
for (i in 2:10^3) set(dt, j = paste('col', as.character(i), sep = ''), value = dt[[i-1]] * 0.95^(i-1))

將這些視為代表“每日死亡率”。 我想計算每月的存活率,所以我有以下代碼塊:

dt[, paste0('surv_rate_', 1:10^3) := Reduce('*', (1-dt[, paste0('col', 1:10^3)])^30, accumulate = T)]

我無法找到如上所示的行累積產品的任何基准測試。

您能想到以 data.table 方式執行此操作的任何更好/更清潔/更快的方法嗎?

(我也想到了as.data.table(t(cumprod(t(dt)))但這似乎永遠需要這個大小的表)

正如評論中提到的,另一種可能的解決方案是沿行使用apply

res1 <- 
 copy(dt)[, paste0('surv_rate_', 1:10^3) := transpose(apply((1-.SD)^30,1,cumprod,simplify=F))] 

res2 <- copy(dt)[, paste0('surv_rate_', 1:10^3) := Reduce('*', (1-dt[, paste0('col', 1:10^3)])^30, accumulate = T)]

all.equal(res1,res2)
[1] TRUE

但是,您的解決方案仍然快 30%:

Unit: milliseconds
                                                                                                                   expr       min
          copy(dt)[, `:=`(paste0("surv_rate_", 1:10^3), transpose(apply((1-.SD)^30, 1, cumprod, simplify = F)))] 1011.7095
 copy(dt)[, `:=`(paste0("surv_rate_", 1:10^3), Reduce("*", (1-dt[, paste0("col", 1:10^3)])^30, accumulate = T))]  793.5415
       lq     mean   median       uq      max neval
 1246.993 1743.854 1546.797 2119.166 2772.646    10
 1046.194 1314.569 1249.636 1405.414 2496.858    10

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM