【发布时间】:2014-02-28 06:46:04
【问题描述】:
我想从文本文件中获取列名和行名,并使用行和列信息构建一个稀疏矩阵(该算法可以在下面的描述中找到)。我有一个可行的解决方案,但对于包含超过 3,000,000 个条目的文本文件来说速度很慢。
是否有人对比我在下面描述的算法更快的算法有任何建议?
首先,我从一个文本文件开始,该文件提供列名和行名,以空格分隔。例如:
aaaa 11111 22222 33333 bbbb 11111 22222 cccc 11111
其中{aaaa,bbbb,cccc} 是4 个字符的列名,{11111,22222,33333} 是5 个字符的行名。
其次,我使用扫描功能将此文本文件加载到R:
char_vec <- scan(file = "textFile.txt", what = "character")
将 textFile 信息转换为字符向量。
第三,我找到所有可能的列名和行名:
c_names <- unique(char_vec[nchar(char_vec) == 4])
r_names <- unique(char_vec[nchar(char_vec) == 5])
第四,我从数据中创建一个稀疏矩阵:
library(Matrix)
createMatrix <- function(char_vec=char_vec, c_names=c_names, r_names=r_names)
{
mySparseMatrix <- Matrix(0, nrow = length(r_names), ncol = length(c_names),
sparse = TRUE)
for (i1 in 1:length(char_vec))
{
if (char_vec[i1] %in% c_names)
{
c_index <- match(char_vec[i1], c_names)
}
if (char_vec[i1] %in% r_names)
{
r_index <- match(char_vec[i1], r_names)
mySparseMatrix[r_index, c_index] <- 1
}
}
colnames(mySparseMatrix) <- c_names
rownames(mySparseMatrix) <- r_names
return(mySparseMatrix)
}
这给出了这个输出:
aaaa bbbb cccc
11111 1 1 1
22222 1 1 .
33333 1 . .
为了展示这个算法的运行速度有多快,我填充了字符向量(尽管以一种不切实际的方式,但我认为它可以作为示例来达到目的):
char_vec <- rep(c("aaaa", "11111", "22222", "33333", "bbbb", "11111", "22222", "cccc", "11111"), 1000)
然后跑:
system.time(createMatrix(char_vec, c_names, r_names))
输出:
user system elapsed
9.89 0.00 9.94
我已经使用:
Rprof("createMatrixOut.out")
z <- createMatrix(char_vec, c_names, r_names)
Rprof(NULL)
并使用以下方法显示输出的子集:
summaryRprof("createMatrixOut.out")$by.total[1:10,]
输出:
total.time total.pct self.time self.pct
"createMatrix" 8.08 100.00 0.08 0.99
"[<-" 7.96 98.51 0.08 0.99
"replCmat4" 7.40 91.58 0.04 0.50
"as" 5.64 69.80 0.04 0.50
"asMethod" 5.06 62.62 0.16 1.98
"standardGeneric" 4.68 57.92 0.24 2.97
"new" 4.52 55.94 0.02 0.25
"initialize" 4.40 54.46 0.04 0.50
"callNextMethod" 4.24 52.48 0.08 0.99
".Call" 4.12 50.99 0.60 7.43
【问题讨论】:
-
您是否尝试分析您的代码以查看它在哪里花费了这么多时间?
-
我没有。我将分析代码并编辑我的问题。
标签: r performance algorithm indexing sparse-matrix