2

Windows 컴퓨터에서 R을 사용하여 현재 d1과 d2를 순환하는 3D 배열 (720x360x1368)에서 중첩 루프를 실행하여 d3 이상의 함수를 적용하고 유사한 차원의 새로운 배열로 출력합니다.3 차원 배열의 중첩 for-loop 병렬 처리 R

다음 재현 가능한 예에서는 실행 속도를 높이기 위해 계수를 10으로 줄였습니다. SPI()는 길이 1368의 $fitted 새로운 배열 cunstruct 각 루프 증분에서 사용되는 특정한리스트의리스트의리스트를 복귀를 SpeI 패키지의 함수이다

library(SPEI) 

old.array = array(abs(rnorm(50)), dim=c(72,36,136)) 

new.array = array(dim=c(72,36,136)) 

for (i in 1:72) { 
    for (j in 1:36) { 
    new.listoflists <- spi(ts(old.array[i,j,], freq=12, start=c(1901,1)), 1, na.rm = T) 
    new.array[i,j,] = new.listoflists$fitted 
    } 
} 

.

이 루프는 완벽하게 작동하지만 계산하는 데 오랜 시간이 걸립니다. 나는 foreach을 사용하여 루프를 for으로 병렬 처리 할 수 ​​있음을 읽었다.

그러나 이전 배열과 새로운 배열의 희미한 이름이 일관되도록 새 배열의 중첩 및 조합을 어떻게 구현할 수 있는지 이해할 수 없습니다.

는 (결국, 나는 as.data.frame.table()를 사용하여 "플랫"긴 패널 데이터 프레임에 이전 및 새 배열을 모두 변환과 세 가지 차원에서 병합하는 것입니다 수있을 무엇을 할 수 있습니다.)

병렬 컴퓨팅을 사용하여 원하는 출력을 얻을 수있는 방법에 대한 도움을 주시면 매우 감사하겠습니다.

건배
CubicTom

+0

난 정말 당신이 (수행 할 작업을 말할 수 없습니다 [재현 예!] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible- 예))) 그러나 당신은 n 차원 배열 전반에 걸쳐 일반화 가능한'apply()'를 사용 했습니까? 'apply()'의 두 번째 인수는 함수를 적용 할 차원을 정의합니다.예를 들어'paste0()'함수를 배열의 세 번째 차원에 적용하려면'apply (old.array, 1 : 2, FUN = function (x) paste0 (x))'를 사용하십시오. –

+0

감사합니다. Simon, 저는 당신의 조언을 따르고 재현 할 수있는 본보기를 만들었습니다. – CubicTom

+0

또한 apply를 사용하여 시도해 보았습니다 : new2.array <- apply (old.array, 1 : 2, FUN = function (x) spi (x, freq = 12, start = c (1901,1)), 1 , na.rm = T))'는 매우 빠르지 만, 72 * 36 = 2592 요소를 갖는 행렬만을 제공합니다. 각 요소는 8의 목록입니다.이 두 번째 요소 중 두 번째 요소 인 $ ($ fitted)은 d3을 따라 각 항목에 해당하는 원하는 함수 값의 목록입니다. – CubicTom

답변

0

여기에 내가 가지고 올 것입니다 재현 예를 더 잘했을 것이다 :

먼저 그럼 당신은 만들

cl <- makeCluster(6, type = "SOCK") 
registerDoSNOW(cl) 

를 사용하도록 클러스터를 생성 루프를 닫고 클러스터를 닫습니다 :

zz <- foreach(i = 1:720, .combine = c) %:% 
foreach(j = 1:360, .combine = c) %dopar% { 
new.listoflists <- FUN(old.array[i,j,]) 
new.array[i,j,] <- new.listoflists$list 
} 
stopCluster(cl) 

이 new.array의 모든 반복을 포함하는 목록 ZZ를 만듭니다 [난, j는,], 당신은 함께 그들을 바인딩 할 수 있습니다 :

new.obj <- plyr::ldply(zz, data.frame) 

희망이 당신을 도와줍니다!

+1

고마워, tia_0! 이것은 내 경우에 for-loops를 병렬 처리하는 방법을 이해하는데 많은 도움이되었다! 나는 이것을 올바른 대답으로 표시한다. 관심있는 독자를 위해 : @ Simon의 대답은 나의 초기 질문에 대한 논평에서도 역시 매력적이다. – CubicTom

0

동작이 올바른지 확인하기 위해 질문의 크기만큼 사용하지 않았습니다. 그래서 여기에 여러 인자를 갖는 mapply를 사용합니다. 결과는 결과 목록입니다. 그런 다음 matrix()로 래핑하여 원하는 차원을 얻습니다. 내가를 사용하여 반복 시간J를 사용하여 반복되고 있습니다. 행렬에 도달 할 때 matrix()가 먼저 행을 기준으로 항목을 놓은 다음 다음 열로 넘어가는 것이 중요합니다.

new.array = array(1:(5*10*4), dim=c(5,10,4)) 

# FUN: function which returns lists of 
FUN <- function(x){ 
    list(lapply(x, rep, times=3)) 
} 

# result of the computation 
result <- matrix(
    mapply(
     function(i,j,...){ 

      FUN(new.array[i,j,]) 
     } 
     ,i = rep(1:nrow(new.array),times=ncol(new.array)) 
     ,j = rep(1:ncol(new.array),each=nrow(new.array)) 
     ,new.array=new.array 
    ) 
    ,nrow=nrow(new.array) 
    ,ncol=ncol(new.array) 
) 
+0

답장을 보내 주셔서 감사합니다. I는 코드를 채택했지만, 어떤 결과 않고 한 시간 후에 실행을 중지 : 'new3.array = 어레이가 계산 # 결과 (=에게 C (72,36,136)를 어둡게) new3.array <- 매트릭스 (mapply ( function (i, j, ...) { spi (old.array [i, j,], freq = 12, 시작 = c (1901,1)), 1, na.rm (1 : nrow (old.array), times = ncol (old.array)) } 어레이)) , old.array = old.array ) , nrow = nrow (old.array) , =을 NcoI을 NcoI (old.array) )' 여기에 누락 된 것이 있습니까? – CubicTom