2017-10-21 70 views
0

我有一個公式可以創建矩陣。後來,每集中的一個矩陣我都要做一些耗時的事情。到目前爲止,我將這些矩陣綁定到一個列表中,其中lapply()。現在,我假設用一組矩陣運算會快得多。事情是,我不知道如何讓這些matrrices生成一個數組,如lapply()如何直接生成矩陣到具有函數的數組中?

我給你這個例子:

# matrix generating function 
mxSim <- function(X, n) { 
    mx = matrix(NA, nrow = n, ncol = 3, 
       dimnames = list(NULL, c("d", "alpha", "beta"))) 
    mx[,1] = rbinom(n, 1, .375) 
    mx[,2] = rnorm(n, 0, 2) 
    mx[,3] = .42 * rnorm(n, 0, 6) 
    return(mx) 
} 

# bundle matrices together 
mx.lst <- lapply(1:1e1, mxSim, n = 1e4) 

# some stuff to be done after, like e. g.: 
lapply(mx.lst, function(m) lm(d ~ alpha + beta, as.data.frame(m))) 

任何人可以給我一些建議如何與一個數組做到這一點?

我一直在尋找到this答案,但它的矩陣必須已經生成了,我只能再次上市前他們幫助我。

+0

我也不知道......但我會建議你去並行(包'snowfall'和/或'foreach') –

+0

我不知道我是否同意你的假設,即一組矩陣比矩陣列表更快。如果您將一個函數應用於一組矩陣中​​的每個矩陣,則可以直接在列表中引入parralelization。對陣列做這樣的操作*要困難得多。 – SeldomSeenSlim

+0

我認爲它與data.frames是一樣的 - 因爲所有東西都是數字的,並且具有相同的維度,所以我使用了矩陣。現在我有所有相同尺寸的矩陣,並再次使用列表(我認爲它有點3D數據框架)。 – jaySf

回答

1

足夠與hooha。讓時間吧。

library(microbenchmark) 
# matrix generating function 
mxSim <- function(X, n) { 
    mx = matrix(NA, nrow = n, ncol = 3, 
       dimnames = list(NULL, c("d", "alpha", "beta"))) 
    mx[,1] = rbinom(n, 1, .375) 
    mx[,2] = rnorm(n, 0, 2) 
    mx[,3] = .42 * rnorm(n, 0, 6) 
    return(mx) 
} 

# bundle matrices together 
mx.lst <- lapply(1:1e1, mxSim, n = 1e4) 

mx.array <- array(mx.lst,dim=c(2,5)) 
# some stuff to be done after, like e. g.: 

#Timing... 
some.fnc<-function(m)lm(d ~ alpha + beta, as.data.frame(m)) 

list.test<-microbenchmark(lapply(mx.lst, some.fnc)) 

array.test<-microbenchmark(apply(mx.array, MARGIN=c(1,2), some.fnc)) 
expr  min  lq  mean median  uq  max neval 
lapply: 74.8953 101.9424 173.8733 146.7186 234.7577 397.2494 100 
apply: 77.2362 101.0338 174.4178 137.153 264.6854 418.7297 100 

天真施加在一個列表的功能,而不是一個陣列在實際性能幾乎相同。

+0

我用1e3矩陣重複了這個顯示板,平均值爲9.83:9.99秒。所以應用版本實際上慢了1.6%。 – jaySf

+0

也許你可以在第二個答案中看看板凳。 – jaySf

0

爲了完整起見,我只是其中n = 1E3做了一些其他基準,如@ SeldomSeenSlim的回答的註釋說明。另外我用data.frames()的名單做了這個,這有點令人驚訝。

這裏是data.frames的功能,對於矩陣函數見上文。

dfSim <- function(X, n) { 
    d <- rbinom(n, 1, .375) 
    alpha <- rnorm(n, 0, 2) 
    beta <- .42 * rnorm(n, 0, 6) 
    data.frame(d, alpha, beta) 
} 

Bundeling

mx.lst <- lapply(1:1e3, mxSim, n = 1e4) 
mx.array <- array(mx.lst, dim = c(2, 500)) 
df.lst <- lapply(1:1e3, dfSim, n = 1e4) 

而且微基準:

some.fnc <- function(m) lm(d ~ alpha + beta, as.data.frame(m)) 
list.test <- microbenchmark(lapply(mx.lst, some.fnc)) 
array.test <- microbenchmark(apply(mx.array, MARGIN = c(1, 2), some.fnc)) 
df.list.test <- microbenchmark(lapply(df.lst, some.fnc)) 

結果

Unit: seconds 
expr   min  lq  mean median  uq  max neval 
lapply  9.658568 9.742613 9.831577 9.784711 9.911466 10.30035 100 
apply  9.727057 9.951213 9.994986 10.00614 10.06847 10.22178 100 
lapply(df) 9.121293 9.229912 9.286592 9.277967 9.327829 10.12548 100 

現在,是什麼我們講這個?

不過,沒關係,是一個大膽的旁註:

microbenchmark((lapply(1:1e3, mxSim, n = 1e4)), (lapply(1:1e3, dfSim, n = 1e4))) 
      expr  min  lq  mean median  uq  max neval cld 
(lapply(mxSim)) 2.533466 2.551199 2.563864 2.555421 2.559234 2.693383 100 a 
(lapply(dfSim)) 2.676869 2.695826 2.718454 2.701161 2.706249 3.293431 100 b 
+1

嗯。 Sehr interessant ...那麼這是否告訴我們它更關心我們如何包裝這些功能?我從這些結果的猜測是(我們知道其中的一部分)是,當我們應用在一個矩陣數組上時,它在內部列出它們(將維度降爲1)。因此DF/lapply的開銷較小。但是爲什麼lapply /矩陣會更快,假設lapply/DF解決方案必須將DF轉換爲mtrx? – SeldomSeenSlim