Цикл Foreach if - PullRequest
       10

Цикл Foreach if

0 голосов
/ 11 мая 2018

У меня есть набор данных, который составляет 60 миллионов строк, и я хочу вычислить сравнение для каждой строки. Это простая разница во времени между двумя метками времени. Для оценки времени выполнения я выполнил расчет на 1 миллион строк, и это заняло почти 2 минуты. Я надеюсь, что есть более быстрый путь.

Вот некоторые примеры данных.

library(data.table)

DT <- fread( 'unique_id,click_time,click_time2
100005361,2017-11-09 03:58:32,2017-11-09 03:59:33
100005372,2017-11-09 00:53:08,2017-11-09 00:53:40
100005373,2017-11-09 04:38:52,2017-11-09 04:38:53
100005374,2017-11-09 05:42:30,2017-11-09 05:44:30' )

Это основной показатель, который я хочу вычислить:

DT$click_diff = difftime(DT$click_time,DT$click_time2,units=c("secs"))

Если я просто запустлю это, я думаю, что это займет часы за часами, поэтому я попытался использовать пакет foreach (), но, думаю, я ошибаюсь.

library(doParallel)
library(foreach)
cl <- makeCluster(parallel::detectCores()-1)
registerDoParallel(cl)   #create a cluster


r <-  foreach(i=1:nrow(DT) %dopar% {

results[i] = difftime(DT$click_time[i],DT$click_time_2[i],units=c("secs"))

return(data.frame(results))
}

parallel::stopCluster(cl)

Кластеры определенно настроены, но ничего не происходит. У кого-нибудь есть советы, как исправить этот код или, возможно, другой способ ускорить расчет разницы во времени для большого набора данных?

1 Ответ

0 голосов
/ 11 мая 2018

Если вы используете тот факт, что R просто представляет время в секундах с данного времени (полночь 1 января 1970 г. по умолчанию), это должно занять тривиальное количество времени в однопоточном режиме.

Генерация данных:

library(data.table)

## Generate Data
RowCount <- 60e6
DT <- data.table(unique_id = seq_len(RowCount),
                 click_time = sample.int(1e5,size = RowCount, replace = TRUE),
                 duration = sample.int(1e2,size = RowCount, replace = TRUE))

DT[,click_time2 := click_time + duration]
DT[,duration := NULL]

DT[, click_time := as.POSIXct(click_time, tz = "UTC", origin = "1970-01-01 00:00:00")]
DT[, click_time2 := as.POSIXct(click_time2, tz = "UTC", origin = "1970-01-01 00:00:00")]


head(DT)
#    unique_id          click_time         click_time2
# 1:         1 1970-01-01 04:50:25 1970-01-01 04:51:08
# 2:         2 1970-01-02 00:53:50 1970-01-02 00:54:43
# 3:         3 1970-01-01 15:58:54 1970-01-01 15:59:18
# 4:         4 1970-01-01 22:36:32 1970-01-01 22:37:48
# 5:         5 1970-01-01 08:51:48 1970-01-01 08:52:17
# 6:         6 1970-01-01 12:24:15 1970-01-01 12:24:30

Рассчитать duration:

system.time({
  DT[,duration := as.integer(click_time2) - as.integer(click_time) ]
})

# user  system elapsed 
# 0.700   0.069   0.772 

Вопрос: даже если вы сохраняете класс difftime и не используете синтаксис data.table, это все равно займет тривиальное время. На вашем компьютере недостаточно памяти?

system.time({
  DT$click_diff = difftime(DT$click_time,DT$click_time2,units=c("secs"))
})

#   user  system elapsed 
#  1.796   0.653   2.452 

head(DT)
#    unique_id          click_time         click_time2 duration
# 1:         1 1970-01-01 21:27:49 1970-01-01 21:29:00  71 secs
# 2:         2 1970-01-01 16:56:37 1970-01-01 16:58:04  87 secs
# 3:         3 1970-01-01 16:30:53 1970-01-01 16:31:28  35 secs
# 4:         4 1970-01-01 21:00:30 1970-01-01 21:01:57  87 secs
# 5:         5 1970-01-01 17:27:53 1970-01-01 17:28:19  26 secs
# 6:         6 1970-01-01 07:52:49 1970-01-01 07:53:19  30 secs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...