Назначение столбцов параллельно data.table
Я хотел бы назначить много (до 2000+) столбцов data.table
; процесс показался мне чрезвычайно распараллеливаемым, но кажется, что процесс распределяется не очень хорошо data.table
многим работникам.
Я ожидал следующего, чтобы работать:
library(data.table)
library(parallel)
NN = 100
JJ = 100
cl = makeCluster(2)
DT = data.table(seq_len(NN))
alloc.col(DT, 1.5*JJ)
clusterExport(cl, c("DT", "NN", "JJ"))
clusterEvalQ(cl, library(data.table))
parLapply(cl, seq_len(JJ), function(jj) {
set(DT, , paste0("V", jj), rnorm(NN))
})
stopCluster(cl)
Однако это приводит к неясной ошибке:
Ошибка в
checkForRemoteErrors(val)
: 2 узла выдали ошибки; Первая ошибка: Внутренняя ошибка, пожалуйста, сообщите (включая результатsessionInfo()
) в datatable-help: oldtncol (0)
Я думаю, это связано с тем, как работает назначение по ссылке. Назначение происходит в каждом потоке, но это не передается обратно DT
в глобальной среде.
Нет ли способа добавить столбцы в data.table
в параллели?
1 ответ
Следующее действительно работает в Linux (Ubuntu 16.04). (примечание: mcapply не работает на Windows) Мне интересно понять, если это быстрее
> DT <- do.call("cbind",
mclapply(seq_len(JJ), function(jj) {
set(DT, , paste0("V", jj), rnorm(NN))
}, mc.cores = detectCores()))
Спектакль
работает на 12 ядрах
NN = 100000
JJ = 100пользовательская система истекла
1,172 2,756 41,707NN = 100
JJ = 2000пользовательская система истекла
4.060 11.152 24.101NN = 1000
JJ = 2000пользовательская система истекла
6,580 15,712 139,967
Предложение
Я использую что-то вроде этого, чтобы получить 2M столбцов и 600 строк (все еще не оптимально), надеюсь, что это соответствует вашим требованиям
system.time(
DT2 <- as.data.table(matrix(rnorm(NN*JJ), ncol = JJ))
)