Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R-每n个元素的快速行和矩阵_R_Matrix - Fatal编程技术网

R-每n个元素的快速行和矩阵

R-每n个元素的快速行和矩阵,r,matrix,R,Matrix,我有一个问题,关于每个第n个元素行的快速求和 考虑一个16列m行的矩阵。结果应该有4列和m行,其中每列是每n个元素的和,即第一列是第1、5、9、13列的和,第二列是第2、6、10、14列的和 目前我通过矩阵乘法来实现这一点。但是,对于大型矩阵,这需要花费太长的时间。发布的解决方案仅对一行中的n个连续元素求和,而不是拆分 /编辑: 以下是我目前解决问题的方法: test <- matrix(c(1:24000),ncol=64) SumFeatures <- function(nco

我有一个问题,关于每个第n个元素行的快速求和

考虑一个16列m行的矩阵。结果应该有4列和m行,其中每列是每n个元素的和,即第一列是第1、5、9、13列的和,第二列是第2、6、10、14列的和

目前我通过矩阵乘法来实现这一点。但是,对于大型矩阵,这需要花费太长的时间。发布的解决方案仅对一行中的n个连续元素求和,而不是拆分

/编辑: 以下是我目前解决问题的方法:

test <- matrix(c(1:24000),ncol=64)

SumFeatures <- function(ncol,nthElement) {
  ncolRes <- ncol/nthElement
  matrix(c(rep(diag(ncolRes),times = nthElement)),ncol = ncolRes,byrow = TRUE)
}

# Get Matrix to sum over every 4th element
sumMatrix <- SumFeatures(ncol(test),4)

system.time(test %*% sumMatrix)

test使用从内置11×8数据框导出的矩阵
m
作为输入
anscombe

# create test matrix m
m <- as.matrix(anscombe)
给予:

          1     2     3     4
 [1,] 18.04 19.14 17.46 14.58
 [2,] 14.95 16.14 14.77 13.76
 [3,] 20.58 21.74 25.74 15.71
 [4,] 17.81 17.77 16.11 16.84
 [5,] 19.33 20.26 18.81 16.47
 [6,] 23.96 22.10 22.84 15.04
 [7,] 13.24 12.13 12.08 13.25
 [8,]  8.26  7.10  9.39 31.50
 [9,] 22.84 21.13 20.15 13.56
[10,] 11.82 14.26 13.42 15.91
[11,] 10.68  9.74 10.73 14.89
   test replications elapsed relative
6   six         1000    0.12    1.000
5  five         1000    0.18    1.500
4  four         1000    0.30    2.500
2   two         1000    0.31    2.583
3 three         1000    0.39    3.250
7 seven         1000    0.58    4.833
1   one         1000    2.27   18.917
2)t轻轻地或这会给出相同的结果:

do.call(cbind, tapply(1:ncol(m), gl(4, 1, ncol(m)), function(ix) rowSums(m[, ix])))
3)tapply-2或给出类似结果的:

matrix(tapply(m, gl(4 * nrow(m), 1, length(m)), sum), nrow(m))
4)应用/array或此操作,这还要求将相同数量的输入列汇总到每个输出列中:

apply(array(m, c(nrow(m), 4, ncol(m) / 4)), 1:2, sum)
注意,在
m
的情况下,这只是
apply(数组(m,c(11,4,2),1:2,sum)

5)对于此备选方案基于
for循环:

res <- 0
for(i in seq(1, ncol(m), 4)) res <- res + m[, seq(i, length = 4)]
res
7)行和

t(rowsum(t(m), gl(4, 1, ncol(m))))
注意:以下测试的解决方案

  • (6) ,(5)和(4)按速度降序排列最快(即(6)最快)。这三个参数还要求
    m
    的列数为4的偶数倍。(2) 是不需要偶数倍数的解决方案中最快的,然后是(3)、(7)和(1),其中(1)是最慢的
  • (7) 是最短的,(1)是次短的,(4)是第三短的
以下是基准:

library(rbenchmark)
benchmark(
  one = t(apply(m, 1, tapply, gl(4, 1, ncol(m)), sum)),
  two = do.call(cbind, 
         tapply(1:ncol(m), gl(4, 1, ncol(m)), function(ix) rowSums(m[, ix]))),
  three = matrix(tapply(m, gl(4 * nrow(m), 1, length(m)), sum), nrow(m)), 
  four = apply(array(m, c(nrow(m), 4, ncol(m) / 4)), 1:2, sum),
  five = {res <- 0
          for(i in seq(1, ncol(m), 4)) res <- res + m[, seq(i, length = 4)]
          res },
  six = matrix(Reduce("+", split(m, gl(ncol(m) / 4, nrow(m) * 4))), nrow(m)),
  seven = t(rowsum(t(m), gl(4, 1, ncol(m)))),
  order = "relative", replications = 1000)[1:4]

根据我的经验,如果将问题简化为内存中相邻的两个一维数组之间的操作,则可以获得绝对最快的计算速度。这通常涉及到重塑数据,这可能是一项昂贵的操作,但如果您需要重复多次计算,这是值得的

以11×8矩阵为例(与G.Grothendieck的解决方案相同),我会这样做

dim(m) <- c(44, 2)
out <- m[, 1] + m[, 2]
dim(out) <- c(11, 4)

dim(m)您能提供一些数据以便我们可以帮助您吗?请参见此处,了解可重复性最低的示例:
   test replications elapsed relative
6   six         1000    0.12    1.000
5  five         1000    0.18    1.500
4  four         1000    0.30    2.500
2   two         1000    0.31    2.583
3 three         1000    0.39    3.250
7 seven         1000    0.58    4.833
1   one         1000    2.27   18.917
dim(m) <- c(44, 2)
out <- m[, 1] + m[, 2]
dim(out) <- c(11, 4)