【发布时间】:2012-09-02 04:13:09
【问题描述】:
我有一个想要居中的大矩阵:
X <- matrix(sample(1:10, 5e+08, replace=TRUE), ncol=10000)
使用 colMeans 可以快速高效地找到方法:
means <- colMeans(X)
但是从每列中减去各自的平均值有什么好的(快速且节省内存的)方法?这可行,但感觉不对:
for (i in 1:length(means)){
X[,i] <- X[,i]-means[i]
}
有没有更好的办法?
/edit:这是 DWin 在更大的矩阵上编写的各种基准测试的修改,包括其他发布的建议:
require(rbenchmark)
X <- matrix(sample(1:10, 5e+07, replace=TRUE), ncol=10000)
frlp.c <- compiler:::cmpfun(function(mat){
means <- colMeans(mat)
for (i in 1:length(means)){
mat[,i] <- mat[,i]-means[i]
}
return(mat)
})
mat.c <- compiler:::cmpfun(function(mat){
t(t(X) - colMeans(X))
})
swp.c <- compiler:::cmpfun(function(mat){
sweep(mat, 2, colMeans(mat), FUN='-')
})
scl.c <- compiler:::cmpfun(function(mat){
scale(mat, scale=FALSE)
})
matmult.c <- compiler:::cmpfun(function(mat){
mat-rep(1, nrow(mat)) %*% t(colMeans(mat))
})
benchmark(
frlp.c=frlp.c(X),
mat=mat.c(X),
swp=swp.c(X),
scl=scl.c(X),
matmult=matmult.c(X),
replications=10,
order=c('replications', 'elapsed'))
matmult 函数似乎是新的赢家!我真的很想在 5e+08 元素矩阵上尝试这些,但我的 RAM 总是用完。
test replications elapsed relative user.self sys.self user.child sys.child
5 matmult 10 11.98 1.000 7.47 4.47 NA NA
1 frlp.c 10 35.05 2.926 31.66 3.32 NA NA
2 mat 10 50.56 4.220 44.52 5.67 NA NA
4 scl 10 58.86 4.913 50.26 8.42 NA NA
3 swp 10 61.25 5.113 51.98 8.64 NA NA
【问题讨论】:
-
也许
scale功能可以帮助你。见?scale。另一个有用的函数可能是sweep。 -
@Jiber:缩放功能比上面的 for 循环慢得多。扫描应该可以,谢谢!
-
谁是'wuber'?
benchmark函数由 Wacek Kusnierczyk 编写。 -
@DWin:抱歉,我引用了您的帖子,但名称错误。我最近在交叉验证上阅读了很多
wuber写的东西。
标签: r center data-manipulation