R снегопад: параллельно применяется к столбцам таблицы

У меня есть таблица M со многими столбцами и строками, полученная из текстового файла:

M <- read.table("text.csv",header=TRUE,sep="\t")

Чтобы получить ранги по столбцам, я успешно использовал:

M <- apply(M,2,rank)

Хотелось бы ускорить вычисления, но реализовать эту функцию в снегопад не удалось.

Я старался :

library(snowfall)
sfStop()
nb.cpus <- 8
sfInit(parallel=TRUE, cpus=nb.cpus, type = "SOCK")
M <- sfClusterApplyLB(M, rank) # does not work
M <- sfClusterApply(M,2,rank) # does not work
M <- sfClusterApplyLB(1:8, rank,M) # does not work

Что эквивалентно M <- apply(M,2,rank) в снегопаде?

Заранее спасибо за вашу помощь !


person Fred    schedule 10.02.2016    source источник
comment
Второй аргумент sfClusterApply должен быть функцией. Он не принимает аргумент маржи.   -  person Steve Weston    schedule 15.02.2016


Ответы (3)


Эквивалент apply при снегопаде равен sfApply. Вот пример:

library(snowfall)
sfInit(parallel=TRUE, cpus=4, type="SOCK")
M <- data.frame(matrix(rnorm(40000000), 2000000, 20))
r <- sfApply(M, 2, rank)
sfStop()

Этот пример работает почти в два раза быстрее, чем последовательная версия на моей машине с Linux, использующей четыре ядра. Это не так уж плохо, учитывая, что rank не требует больших вычислительных ресурсов.

person Steve Weston    schedule 14.02.2016

Вот рабочий пример:

rank_M_df_col_fx=function(i){
  #M<- read.table("text.csv",header=TRUE,sep="\t")
  col_rank=rank(M[,i])
  return(col_rank)
}

M=data.frame(replicate(10,sample(0:100,1000,rep=TRUE)))
n_cols=ncol(M)

library(snowfall)
sfInit(parallel=TRUE) # 
sfExportAll()
rank_results_list=sfLapply(x=c(1:n_cols), fun=rank_M_df_col_fx)
rank_dataframe <- data.frame(matrix(unlist(rank_results_list), nrow=nrow(M), byrow=F))

sfRemoveAll()
sfStop()

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

person Lucas Fortini    schedule 11.02.2016
comment
Большое спасибо за этот очень хороший ответ! Я провел несколько тестов и, как вы указали, параллельный код не работает быстрее, по крайней мере, на моем примере. - person Fred; 11.02.2016
comment
Без проблем! Если мой ответ отвечает на ваш вопрос, вы должны отметить его как правильный ответ... - person Lucas Fortini; 12.02.2016

Большое спасибо за Вашу помощь !

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

Я думаю, что мой код не работал с M ‹- sfClusterApply(M,2,rank), потому что отсутствовал sfExportAll().

Итак, наконец, самое простое решение, работающее для меня:

M <- read.table("text.csv",header=TRUE,sep="\t")
n_cols=ncol(M)
nb.cpus <- 4
library(snowfall)
sfStop()
sfInit(parallel=TRUE, cpus=nb.cpus, type = "SOCK") 
sfExportAll()
M <- sfApply(M,2,rank)
sfRemoveAll()
sfStop()
person Fred    schedule 15.02.2016
comment
Функция rank не нуждается в каких-либо данных из глобальной среды для правильной работы, в то время как функция rank_M_df_col_fx в ответе Лукаса требует. Использование sfExportAll в вашем ответе только тратит время на создание глобальных переменных для рабочих процессов, которые не будут использоваться. Причина, по которой sfClusterApply не работает для вас, заключается в том, что она эквивалентна lapply, а не применяется. - person Steve Weston; 17.02.2016
comment
Спасибо за этот комментарий, Лукас. Это правда, что в простом примере rank sfExportAll бесполезен. В другом более сложном вычислении мне понадобился sfExportAll. - person Fred; 18.02.2016