R data.table Выполнить агрегирование по выбранным строкам с использованием полного набора данных - PullRequest
0 голосов
/ 22 марта 2019

Я вычисляю возможности алгоритма машинного обучения в R с использованием data.table. Я собираюсь делать прогнозы только для строк с будущей датой, но для вычисления каждого объекта мне нужно агрегировать данные в большом наборе данных, который может содержать миллионы строк. Однако, чтобы повысить скорость обработки и производительность, мне не нужно, чтобы агрегат вычислялся по строкам за прошедшую дату.

Проще говоря, я пытаюсь использовать большой набор данных, чтобы вычислить функцию только для последних n строк, используя весь набор данных, и пропустить строки, где дата в прошлом. У меня есть пользовательская функция, которая подсчитывает количество строк, которые превышают текущую строку, вычисляемую в цикле. Мой пример data.table ниже показывает результат, которого я пытаюсь достичь. Вычисляемая строка будет подсчитывать количество строк, превышающих ее, и затем перемещаться к следующей строке в цикле. Я хочу, чтобы он пропускал все строки с прошедшей датой и вычислял только строки с будущей датой. Текущая дата в этом примере: 2019-03-20.

Group         Date  Appt  Sum
    A   2019-03-18     1   NA
    A   2019-03-19     1   NA
    A   2019-03-20     1   NA
    A   2019-03-21     1    3
    A   2019-03-22     1    4
    A   2019-03-23     1    5

library(data.table)
dt = structure(list(Group = c("A", "A", "A", "A", "A", "A"), Date = structure(c(17973, 
17974, 17975, 17976, 17977, 17978), class = "Date"), Appt = c(1L, 
1L, 1L, 1L, 1L, 1L), Sum = c(NA, NA, NA, 3, 4, 5)), row.names = c(NA, 
-6L), class = "data.frame")
setDT(dt)

Это функция и код, который я сейчас использую, и он отлично работает. Единственная проблема заключается в том, что он выполняет вычисления для каждой строки, хотя мне нужны только результаты расчета для нескольких строк в конце набора данных, которые могут быть в миллионах. Он тратит массу вычислительной мощности и времени на выполнение вычислений, которые будут исключены из набора прогнозов.

rollingSum <- function(i, data, count, dates) {
  z <- with(data[i, ], zoo(count, dates))
  g <- zoo(, seq(start(z), end(z), by="day"))
  m <- merge(z, g)
  window(rollapplyr(m, 365, sum, na.rm=TRUE, partial=TRUE), time(z))
}

dt[, Sum := as.numeric(rollingSum(data=dt, count=Appt, dates=Date) - Appt), by=Group]

1 Ответ

1 голос
/ 22 марта 2019

вот некоторые подробности для моего комментария выше:

dt <- data.table(
  Group = "A",
  Date = as.IDate(c("2019-03-18", "2019-03-19", "2019-03-20",
                    "2019-03-21", "2019-03-22","2019-03-23")),
  Appt = 1)


microbenchmark(
  dt[, Sum := as.numeric(rollingSum(data=dt, count=Appt, dates=Date) - Appt), by=Group],
  dt[, Sum2 := ifelse(Date > as.IDate("2019-03-20"), (1:.N) - Appt , as.numeric(NA)), by = Group],unit = "ms")

вот критерии:

Unit: milliseconds
       expr      min        lq      mean   median       uq         max neval
 rollingSum 3.463955 4.0644910 18.748804 4.353562 4.745325 1395.840823   100
   new func 0.768079 0.8757095  1.258782 1.015766 1.140316    8.275985   100
...