优化性能,同时循环遍历数据表并使用 set 函数。

huangapple go评论84阅读模式
英文:

Improving performance while looping over data.table with set

问题

  1. 我想知道是否有更好的方法来编写以下代码以提高性能
  2. 我的真实数据集有120,000ID每个ID25
  3. 我想对每行应用指数预测
  4. library(data.table)
  5. #虚拟数据集
  6. dt <- data.table(
  7. ID = rep(c("A","B"), each=5),
  8. Value = abs(round(rnorm(10)*10))
  9. )
  10. #初始化第一行的列和值
  11. dt[, SES := 0]
  12. #按ID拆分成列表以便用lapply循环
  13. dt <- split(dt, dt$ID)
  14. #用于循环的函数
  15. alpha <- 0.3
  16. loop_function <- function(x) {
  17. for(i in 2L:5L) {
  18. set(x, i, "SES", round(x[i, alpha * Value] + x[i-1L, (1L - alpha) * SES], 0))
  19. }
  20. return(x)
  21. }
  22. #将函数应用于列表元素并绑定结果
  23. dt <- lapply(dt, loop_function)
  24. dt <- rbindlist(dt)
英文:

I wonder if there is a better way to code the following to improve the performance.

My real data set has 120k id's with each 25 rows.

I would like to apply an exponential forecast rowise

  1. library(data.table)
  2. #dummy data set
  3. dt &lt;- data.table(
  4. ID = rep(c(&quot;A&quot;,&quot;B&quot;), each=5),
  5. Value = abs(round(rnorm(10)*10))
  6. )
  7. #Initialize column and value for 1st row
  8. dt[, SES := 0]
  9. #split by ID into list to loop over with lapply
  10. dt &lt;- split(dt, dt$ID)
  11. #function to loop with
  12. alpha &lt;- 0.3
  13. loop_function &lt;- function(x) {
  14. for(i in 2L:5L) {
  15. set(x, i, &quot;SES&quot;, round(x[i, alpha * Value] + x[i-1L, (1L - alpha) * SES], 0))
  16. }
  17. return(x)
  18. }
  19. #apply function to list elements and bind result
  20. dt &lt;- lapply(dt, loop_function)
  21. dt &lt;- rbindlist(dt)

答案1

得分: 2

这应该快得多:

  1. library(data.table)
  2. # 虚拟数据集
  3. dt <- data.table(
  4. ID = rep(c("A","B"), each=5),
  5. Value = abs(round(rnorm(10)*10))
  6. )
  7. # 初始化第一行的列和值
  8. dt[, SES := 0]
  9. # 创建索引并进行迭代
  10. dt[, idx:= rowid(ID)]
  11. for(i in 2:max(dt$idx))
  12. {
  13. prev <- dt[idx==(i-1L), SES]
  14. dt[idx==i, SES:= {
  15. round(alpha * Value + (1L - alpha) * prev, 0)
  16. }]
  17. }

这与您的想法非常相似,意味着它会在索引上进行迭代(2:5L),但以一种经过优化的data.table方式。希望这有所帮助 优化性能,同时循环遍历数据表并使用 set 函数。

英文:

This should be much faster:

  1. library(data.table)
  2. #dummy data set
  3. dt &lt;- data.table(
  4. ID = rep(c(&quot;A&quot;,&quot;B&quot;), each=5),
  5. Value = abs(round(rnorm(10)*10))
  6. )
  7. #Initialize column and value for 1st row
  8. dt[, SES := 0]
  9. # Create index and iterate over it
  10. dt[, idx:= rowid(ID)]
  11. for(i in 2:max(dt$idx))
  12. {
  13. prev &lt;- dt[idx==(i-1L), SES]
  14. dt[idx==i, SES:= {
  15. round(alpha * Value + (1L - alpha) * prev, 0)
  16. }]
  17. }

It is in the end pretty similar to your idea, meaning it iterates over indexes (2:5L) but in an optimised, data.table way. Hope this helps 优化性能,同时循环遍历数据表并使用 set 函数。

huangapple
  • 本文由 发表于 2023年5月28日 13:13:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76350031.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定