Улучшение вычислительного времени R для циклов - PullRequest
0 голосов
/ 11 сентября 2018

Попытка запустить функцию сплайна по строкам (690075) в кадре данных (Camera1) с 4096 столбцами (каждый столбец представляет позицию на оси x), где входной переменной для функции является столбец в другом наборе данных того жедлина (тест $ vr) с использованием цикла for;но у меня серьезные проблемы с вычислительным временем.

Я пытался преобразовать фрейм данных в матрицу и сохранить выходные данные в списке среди других, но безрезультатно.Я должен сделать это для 2 других фреймов данных (camera2, camera3) того же размера.

Код

 # Note camera1 and test$vr are of the same length
 # Initialize
 final.data1 <- data.frame()

 #new wavelength range
 y1 <- round(seq(from = 4714 , to = 4900, length.out = 4096),3)

 system.time({
   for (i in 1:690075) {
       w1 = (as.numeric(colnames(camera1[-1]))) * (1.0 + test$vr[i]/299792.458)
       my.data1<-as.data.frame(t(splinefun(x = w1, y = camera1[i,][-1])(y1)))
       colnames(my.data1)=y1
       final.data1 <- bind_rows(final.data1, my.data1)
     } })

Запуск на коробке Ubuntu с оперативной памятью 344 ГБ и30-ядерный процессор Intel (R) Xeon (R) E5-2695 @ 2,30 ГГц

Любые предложения будут с благодарностью.Спасибо.

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Сначала удалите все инструкции, которые можно выполнить один раз, и поместите их вне цикла for.Например: colnames и as.numeric.

Во-вторых, попробуйте векторизовать.Кажется, что вычисление w1 может быть векторизовано и, таким образом, вычислено один раз за пределами цикла for, просто удалив [i].

В-третьих, инициализируйте final.data1 до конечного измерения.Для каждой строки, добавленной к этому data.frame, R создаст новый data.frame с еще одной строкой, а затем удалит предыдущий data.frame.Это займет много времени.Таким образом, final.data1 <- matrix(NA, ncol=length(y1), nrow=NROW).

И, наконец, если вы хотите использовать более одного ядра, попробуйте заменить цикл for на распараллеленный foreach loop.Это возможно, если все строки независимы:

require(foreach)
require(doSNOW)
cl <- makeCluster(25, type="FORK") # FORK not usable in Windows
registerDoSNOW(cl) # register the cluster
clusterExport(cl, c("objects", "needed", "by", "each", "iteration"), envir=environment()) # for example y1, w1 and camera1
final.data1<- foreach(i=icount(NROW), .combine=rbind, inorder=FALSE) %dopar%
{
  # your R code
}
stopCluster(cl)
0 голосов
/ 11 сентября 2018

Не видя данных, нелегко оптимизировать ваш код, но я бы начал с чего-то следующего:

final.data1 <- matrix(nrow = 690075, ncol = 4096)

#new wavelength range
y1 <- round(seq(from = 4714 , to = 4900, length.out = 4096), 3)

system.time({
   w1 <- (as.numeric(colnames(camera1[-1]))) * (1.0 + test$vr/299792.458)
   for (i in 1:690075) {
       my.data1 <- t(splinefun(x = w1[i], y = camera1[i, ][-1])(y1))
       final.data1[i, ] <- my.data1
   }
})

final.data1 <- as.data.frame(final.data1)
colnames(final.data1) <- y1

Пояснение:

  1. Я начинаю с определения объекта класса matrix для хранения результатов. Я считаю, что я правильно понял размеры вашего окончательного data.frame. Это сокращает время работы, потому что

    • Матрицы намного быстрее, чем кадры данных, они представляют собой просто сложенные векторы, и индексация выполняется быстро. Фреймы данных, напротив, представляют собой списки, которые могут содержать все типы данных, числовые, символьные, логические, другие списки и т. Д., И поэтому доступ к их элементам медленный.

    • Резервирование полной памяти результата за одну операцию экономит рутинную работу R с управлением памятью. Расширение final.data1 на каждую итерацию цикла занимает очень много времени.

  2. w1 вычисляется вне цикла с использованием векторизованной природы R. Кроме того, вы повторяли вычисления as.numeric(colnames(camera1[-1])) 690k раз!

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...