более быстрый способ применения применить в большом массиве (возможно, с использованием распараллеливания)? - PullRequest
0 голосов
/ 09 ноября 2018

У меня большой массив в R, скажем,

A = array(rnorm(100*100*30*30*100),dim=c(100,100,30,30,100))

Я бы хотел найти первую запись в 4-м измерении, которая меньше 1:

first_entry = apply(A,c(1,2,3,5),function(x) min(which(x < 1)))

Поскольку массив такой большой, на моем компьютере это займет некоторое время, около 20 секунд, и я собираюсь сделать это для большого количества массивов в будущем. Цикл for примерно такой же скорости. Я также пытался использовать parApply, но это занимает примерно то же время, если не дольше. Возможно, моя функция недостаточно сложна для распараллеливания, чтобы реализовать увеличение скорости. Есть ли более быстрый способ сделать это? И на самом деле, то, что я хотел бы сделать в идеале, это установить значения в другом массиве B (который имеет те же размеры, что и A) в 0. Итак, что-то вроде

B[first_entry] = 0

Обратите внимание, что это не работает, учитывая текущий вывод команды «apply» (см. Выше), поскольку размер first_entry равен 100x100x30x100.

1 Ответ

0 голосов
/ 10 ноября 2018

Я немного упростил ваш пример (моя машина может работать медленнее, чем ваш!) И добавил некоторые измерения времени.Когда я использую parApplym, а не applym, код работает немного быстрее (2,4 секунды с parApply против 3.8 с apply).

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

# Create data
A = array(rnorm(100*100*30),dim=c(100,100,30))

# Using apply
start.time <- Sys.time()
first_entry = apply(A,c(1,2,3),function(x) min(which(x < 1)))
print(Sys.time() - start.time)

# Load packages
library(parallel)

# Create cluster and export
nrCores <- detectCores()
cl <- makeCluster(nrCores)
clusterExport(cl=cl, varlist=c("A"))

# Using parApply
start.time <- Sys.time()
first_entry = parApply(cl=cl,A,c(1,2,3),function(x) min(which(x < 1)))
print(Sys.time() - start.time)
...