R 计算大型矩阵非对角平均值的快速方法

R 计算大型矩阵非对角平均值的快速方法,r,matrix,average,R,Matrix,Average,我需要计算n×n矩阵中每个非对角元素的平均值。上下三角形是冗余的。以下是我当前使用的代码: A <- replicate(500, rnorm(500)) sapply(1:(nrow(A)-1), function(x) mean(A[row(A) == (col(A) - x)])) 我想: mean(c(1,2,3)) mean(c(1,2)) mean(1) 您可以使用以下功能: diagmean <- function(x){ id <- row(x)

我需要计算n×n矩阵中每个非对角元素的平均值。上下三角形是冗余的。以下是我当前使用的代码:

A <- replicate(500, rnorm(500))
sapply(1:(nrow(A)-1), function(x) mean(A[row(A) == (col(A) - x)]))
我想:

 mean(c(1,2,3))
 mean(c(1,2))
 mean(1)

您可以使用以下功能:

diagmean <- function(x){
  id <- row(x) - col(x)
  sol <- tapply(x,id,mean)
  sol[names(sol)!='0']
}
请注意,此函数同时计算上部和下部三角形。您可以使用以下公式仅计算下三角形:

diagmean <- function(A){
  id <- row(A) - col(A)
  id[id>=0] <- NA
  tapply(A,id,mean)
}
diagmean diagmean(A)
-3  -2  -1 
1.0 1.5 2.0 

只需使用线性寻址直接提取对角线,您就可以大大加快速度:
超级对角线
这里从A中提取第i个超级对角线(i=1是主对角线)


superdiag非常好,在我的机器上,1k^2矩阵小于1s。非常感谢索引的使用。我投票赞成这个答案,因为它说明了指数是多么强大。谢谢你,但你的答案要清楚得多,@JorisMeys;只有当你必须做很多事情,并且每十分之一秒就会有广告出现时,这种方法才值得额外的复杂化。它非常聪明——我必须通过索引生成来了解发生了什么。谢谢你的回答,我想说这两个答案都是“酷”的,都说明了
R
的一个或另一个特性。为你们俩干杯。
diagmean <- function(x){
  id <- row(x) - col(x)
  sol <- tapply(x,id,mean)
  sol[names(sol)!='0']
}
> system.time(diagmean(A))
   user  system elapsed 
   2.58    0.00    2.58 

> system.time(sapply(1:(nrow(A)-1), function(x) mean(A[row(A) == (col(A) - x)])))
   user  system elapsed 
  38.93    4.01   42.98 
diagmean <- function(A){
  id <- row(A) - col(A)
  id[id>=0] <- NA
  tapply(A,id,mean)
}
> A <- matrix(rep(c(1,2,3,4),4),ncol=4)

> sapply(1:(nrow(A)-1), function(x) mean(A[row(A) == (col(A) - x)]))
[1] 2.0 1.5 1.0

> diagmean(A)
 -3  -2  -1 
1.0 1.5 2.0 
superdiag <- function(A,i) {
  n<-nrow(A); 
  len<-n-i+1;
  r <- 1:len; 
  c <- i:n; 
  indices<-(c-1)*n+r; 
  A[indices]
}

superdiagmeans <- function(A) {
  sapply(2:nrow(A), function(i){mean(superdiag(A,i))})
}
> A <- replicate(1000, rnorm(1000))

> system.time(sapply(1:(nrow(A)-1), function(x) mean(A[row(A) == (col(A) - x)])))
   user  system elapsed 
 26.464   3.345  29.793 

> system.time(superdiagmeans(A))
   user  system elapsed 
  0.033   0.006   0.039