Data.table: shift () в data.table v1.9.6 работает медленно для многих групп

Созданный на 11 февр. 2016  ·  3Комментарии  ·  Источник: Rdatatable/data.table

Всем привет!
Для многих разных групп в by , shift намного медленнее, чем ручное переключение.
См. Http://stackoverflow.com/questions/35179911/shift-in-data-table-v1-9-6-is-slow-for-many-groups
и https://github.com/nachti/datatable_test/blob/master/leadtest.R для подробного примера.
Ваше здоровье,
Герхард

GForce performance

Самый полезный комментарий

@ ben519 Fyi , для особого случая, когда ваш код выглядит так, есть ярлык:

library(data.table)
dt <- data.table(Grp = rep(seq_len(1e6), each=10L))
dt[, Value := sample(100L, size = .N, replace = TRUE)]

system.time(dt[, PrevValueByGrp := shift(Value, type = "lag"), by = Grp][])
#    user  system elapsed 
#   19.50    0.80   20.34
system.time(dt[, v := shift(Value, type = "lag")][rowid(Grp)==1L, v := NA][])
#    user  system elapsed 
#    1.00    0.87    1.25 

dt[, all.equal(v, PrevValueByGrp)]
# [1] TRUE

Все 3 Комментарий

Это не удивительно. Это исчезнет, ​​когда gforce будет оптимизирован для := . Я считаю, что это в списке для этого выпуска.

+1 за это повышение производительности. shift() - это основное узкое место в моем коде. Похоже, что для фиксированного количества строк время, необходимое для выполнения shift() , пропорционально количеству групп в данных.

library(data.table)

# Build table to store timings
timings <- CJ(RowCount = 10^7, Groups = 10^c(0:7))
timings[, SizePerGroup := RowCount/Groups]

# Loop through each experiment
for(i in 1:nrow(dt)){
  print(paste0("Iteration: ", i))

  # Build dataset
  timings_i <- timings[i]
  dt <- data.table(Grp = rep(seq_len(timings_i$Groups), each = timings_i$SizePerGroup))
  dt[, Value := sample(100, size = .N, replace = T)]

  # Measure the time it takes to insert a column indicating the previous value by group
  elapsed <- system.time(dt[, PrevValueByGrp := shift(Value, type = "lag"), by = Grp])["elapsed"]
  timings[i, Elapsed := elapsed]
}

library(ggplot2)
ggplot(timings, aes(x = Groups, y = Elapsed))+geom_line()+geom_point()

screen shot 2018-11-10 at 1 08 15 pm

@ ben519 Fyi , для особого случая, когда ваш код выглядит так, есть ярлык:

library(data.table)
dt <- data.table(Grp = rep(seq_len(1e6), each=10L))
dt[, Value := sample(100L, size = .N, replace = TRUE)]

system.time(dt[, PrevValueByGrp := shift(Value, type = "lag"), by = Grp][])
#    user  system elapsed 
#   19.50    0.80   20.34
system.time(dt[, v := shift(Value, type = "lag")][rowid(Grp)==1L, v := NA][])
#    user  system elapsed 
#    1.00    0.87    1.25 

dt[, all.equal(v, PrevValueByGrp)]
# [1] TRUE
Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

lux5 picture lux5  ·  3Комментарии

tcederquist picture tcederquist  ·  3Комментарии

andschar picture andschar  ·  3Комментарии

mattdowle picture mattdowle  ·  3Комментарии

sengoku93 picture sengoku93  ·  3Комментарии