2015-11-18 48 views
0

我需要將矩陣的非零元素的索引保存到文件中。這非常適用於小型矩陣存儲非零指標的行數在a和非零指數的列數在b將非零矩陣元素的索引有效地保存到文件中

X <- matrix(c(1,0,3,4,0,5), byrow=TRUE, nrow=2);  
a <- row(X)[which(!X == 0)] 
b <- col(X)[which(!X == 0)] 

但矩陣的大小是巨大的,我需要找到一種將索引保存到txt文件的有效方法,這樣我就有了[1] b [1](新行)a [2] b [2],依此類推。有什麼建議麼?

回答

4

包裝Matrix對極大的矩陣有很好的解決方案。該sparseMatrix對象可歸納爲一個data.frame其中ij是你的指標和x是值:

X <- matrix(c(1,0,3,4,0,5), byrow=TRUE, nrow=2);  
a <- row(X)[which(!X == 0)] 
b <- col(X)[which(!X == 0)] 

library(Matrix) 
Y <- Matrix(X, sparse = TRUE) 
(res <- summary(Y)) 
    2 x 3 sparse Matrix of class "dgCMatrix", with 4 entries 
    i j x 
    1 1 1 1 
    2 2 1 4 
    3 1 3 3 
    4 2 3 5 
class(res) 
    [1] "sparseSummary" "data.frame" 

然後,您可以子集得到的只是ij

res[, c("i", "j")] 
    i j 
1 1 1 
2 2 1 
3 1 3 
4 2 3 
2

你可以使用參數arr.ind=TRUE使用which,將結果寫入文件write.table

可以抓取所有非零位置的行和列0
write.table(which(X != 0, arr.ind=TRUE), "file.txt", row.names=F, col.names=F) 

這產生對指定的文件中的元素的空間分隔的輸出:

1 1 
2 1 
1 3 
2 3 

使用whicharr.ind=TRUE節省相比張貼在您的問題的代碼通過您的輸入矩陣的幾個掃描,所以在計算輸出數據時應該快一點。可以用對於較大矩陣的基準看到此(1000×1000,用1%的密度):

set.seed(144) 
bigX <- matrix(sample(c(rep(0, 99), 1), 1000000, replace=T), nrow=1000) 
OP <- function(X) cbind(row(X)[which(!X == 0)], col(X)[which(!X == 0)]) 
josilber <- function(X) which(X != 0, arr.ind=TRUE) 

library(microbenchmark) 
microbenchmark(OP(bigX), josilber(bigX)) 
# Unit: milliseconds 
#   expr  min  lq  mean median  uq  max neval 
#  OP(bigX) 20.513535 23.014517 36.463423 25.354250 59.130520 65.50304 100 
# josilber(bigX) 3.873165 4.281624 6.741824 5.250777 6.998415 45.02542 100 

在這種情況下,我們看到在計算非零行和列的5倍的加速。根據矩陣的密度和大小,輸出操作(write.table)可能會成爲瓶頸,在這種情況下,此方法可能沒有太多好處。

相關問題