2016-03-16 5 views
0

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

Пусть: DataP большой набор данных: ID, x1, x2, x3, группа

Мой код:

# Data preparations 
# I split an index (indx) because data split takes a lot of time with my data. 
setkey(DataP ,SplitKey_f) 
indx<-split(seq(nrow(DataP)),DataP $group) 
l<-length(unique(DataP$group)) 

library(parallel) 
library(doParallel) 
library(foreach) 
cl<-makeCluster(8) 
registerDoParallel(cl) 

foreach(i=1:l, .combine = rbind) %dopar% { 
    library(data.table) 
    Psubset<-DataP [,indx[[i]]] 
    # some transformations on the data 
} 
stopCluster(cl) 

выше не работает, потому что Еогеасп с параллельных вычислений не может выполнить линия:

Psubset < -DataP [, indx [[i]]]).

Однако% do% вместо% dopar% работает хорошо (но много времени).

Как исправить проблему - быстрая подстановка данных.table в параллельном цикле?

+1

'data.table' на самом деле не поддерживает параллельные вычисления. Механизмы привязки не очень хорошо работают с параллельными вычислениями. Причина вашего распараллеливания заключается в том, что вы вызываете функцию * в * data.table, которая занимает много времени, вам лучше обслуживать, не используя data.table. Однако это не похоже на вас («некоторые преобразования по данным»). Я подозреваю, что ваша фактическая проблема заключается в том, что вы действительно не используете data.table хорошо. (Я также отмечаю, что вы не назначаете цикл foreach, который указывает, что вы не поняли «foreach».) – Roland

+2

Вы должны описать (включая воспроизводимый пример) то, что вы на самом деле пытаетесь достичь, чтобы люди могут предлагать улучшения вашего кода data.table без необходимости распараллеливания. – Roland

+1

Это может быть интересно вам https://github.com/jangorecki/big.data.table –

ответ

3

Комментарий от @Roland выше, независимо от того, я действительно нашел, что этот тип подхода может быть очень эффективным, и я использовал его для распараллеливания миллионов вычислений над миллионами строк на 40-ядерном экземпляре EC2.

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

Попробуйте следующее:

out <- 
    foreach(i = indx, .packages = c('data.table'), .combine = data.table::rbind) %dopar% { 
    Psubset<-DataP[i,] 
    # do some operations on Psubset 
    } 

Или, если по какой-то причине combine не работает или нуждается в дополнительных аргументов вы можете сделать это после того, как факт.

out_list <- 
    foreach(i = indx, .packages = c('data.table')) %dopar% { 
    Psubset<-DataP[i,] 
    # do some operations on Psubset 
    ) 
    } 
out <- rbindlist(outlist) #, fill=TRUE, etc. 

Если это не сработает, я бы взглянуть на индекс, так что он работает больше как:

out <- 
    foreach(i = 1:max_indx, .packages = c('data.table'), .combine = data.table::rbind) %dopar% { 
    Psubset<-DataP[indx==i,] 
    # do some operations on Psubset 
    } 

Но без воспроизводимым примера трудно понять, какой из них будет работать лучше.

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