web-dev-qa-db-ja.com

巨大なベクトルのリストをより効率的に行列に変換する方法は?

各要素が長さ110の文字ベクトルである長さ130,000のリストがあります。このリストを次元1,430,000 * 10の行列に変換したいと思います。どうすればより効率的に行うことができますか?\私のコードは次のとおりです:

output=NULL
for(i in 1:length(z)) {
 output=rbind(output,
              matrix(z[[i]],ncol=10,byrow=TRUE))
}
57
user1787675

これは現在のコードと同等であり、はるかに高速である必要があります。

output <- matrix(unlist(z), ncol = 10, byrow = TRUE)
120
flodel

I 考える欲しい

output <- do.call(rbind,lapply(z,matrix,ncol=10,byrow=TRUE))

つまり、@ BlueMagisterのdo.call(rbind,...)の使用とlapplyステートメントを組み合わせて、個々のリスト要素を11 * 10マトリックスに変換します...

ベンチマーク(@flodelのunlistソリューションは、私のものより5倍高速で、元のアプローチよりも230倍高速です...)

n <- 1000
z <- replicate(n,matrix(1:110,ncol=10,byrow=TRUE),simplify=FALSE)
library(rbenchmark)
origfn <- function(z) {
    output <- NULL 
    for(i in 1:length(z))
        output<- rbind(output,matrix(z[[i]],ncol=10,byrow=TRUE))
}
rbindfn <- function(z) do.call(rbind,lapply(z,matrix,ncol=10,byrow=TRUE))
unlistfn <- function(z) matrix(unlist(z), ncol = 10, byrow = TRUE)

##          test replications elapsed relative user.self sys.self 
## 1   origfn(z)          100  36.467  230.804    34.834    1.540  
## 2  rbindfn(z)          100   0.713    4.513     0.708    0.012 
## 3 unlistfn(z)          100   0.158    1.000     0.144    0.008 

これが適切にスケーリングする場合(つまり、メモリの問題に遭遇しない場合)、完全な問題は、同等のマシンで約130 * 0.2秒= 26秒かかります(2年前のMacBook Proでこれを行いました)。

15
Ben Bolker

出力に関するサンプル情報があると役立ちます。ますます大きなものにrbindを再帰的に使用することは推奨されません。あなたを助ける何かで私の最初の推測:

z <- list(1:3,4:6,7:9)
do.call(rbind,z)

必要に応じて、効率を高めるために 関連する質問 を参照してください。

5
Blue Magister

使用することもできます

output <- as.matrix(as.data.frame(z))

メモリ使用量は非常に似ています

output <- matrix(unlist(z), ncol = 10, byrow = TRUE)

mem_changed()library(pryr)で確認できます。

0
csta