gpt4 book ai didi

r - 在 R 中的大矩阵中添加连续的四/n 个数字

转载 作者:行者123 更新时间:2023-12-04 09:18:13 25 4
gpt4 key购买 nike

我有非常大的数据集,维度为 60K x 4 K .我正在尝试在每行列中连续添加每四个值。以下是较小的示例数据集。

    set.seed(123)
mat <- matrix (sample(0:1, 48, replace = TRUE), 4)

[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,] 0 1 1 1 0 1 1 0 1 1 0 0
[2,] 1 0 0 1 0 1 1 0 1 0 0 0
[3,] 0 1 1 0 0 1 1 1 0 0 0 0
[4,] 1 1 0 1 1 1 1 1 0 0 0 0

这是我正在尝试执行的操作:
mat[1,1] + mat[1,2] + mat[1,3] + mat[1,4] = 0 + 1 + 1 + 1 = 3

即每四个值相加并输出。
mat[1,5] + mat[1,6] + mat[1,7] + mat[1,8] = 0 + 1 + 1 + 0 = 2

继续到矩阵的末尾(这里是 12)。
mat[1,9] + mat[1,10] + mat[1,11] + mat[1,12] 

完成第一行后,将相同的内容应用于第二行,例如:
mat[2,1] + mat[2,2] + mat[2,3] + mat[2,4] 
mat[2,5] + mat[2,6] + mat[2,7] + mat[2,8]
mat[2,9] + mat[2,10] + mat[2,11] + mat[2,12]

结果将是 nrow x (ncol)/4矩阵。

预期的结果将如下所示:
          col1-col4      col5-8   col9-12
row1 3 2 2
row2 2 2 1
row3 2 3 0
row4 3 4 0

类似地,第 3 行到矩阵中的行数。我怎样才能有效地循环这个。

最佳答案

虽然马修的回答非常酷(+1,顺便说一句),但如果您避免使用 apply,您可以获得更快(~100 倍)的解决方案。并使用 *Sums函数(在本例中为 colSums ),以及一些向量操作技巧:

funSums <- function(mat) {
t.mat <- t(mat) # rows become columns
dim(t.mat) <- c(4, length(t.mat) / 4) # wrap columns every four items (this is what we want to sum)
t(matrix(colSums(t.mat), nrow=ncol(mat) / 4)) # sum our new 4 element columns, and reconstruct desired output format
}
set.seed(123)
mat <- matrix(sample(0:1, 48, replace = TRUE), 4)
funSums(mat)

产生所需的输出:
     [,1] [,2] [,3]
[1,] 3 2 2
[2,] 2 2 1
[3,] 2 3 0
[4,] 3 4 0

现在,让我们制作一些真正的尺寸并与其他选项进行比较:
set.seed(123)
mat <- matrix(sample(0:1, 6e5, replace = TRUE), 4)

funApply <- function(mat) { # Matthew's Solution
apply(array(mat, dim=c(4, 4, ncol(mat) / 4)), MARGIN=c(1,3), FUN=sum)
}
funRcpp <- function(mat) { # David's Solution
roll_sum(mat, 4, by.column = F)[, seq_len(ncol(mat) - 4 + 1)%%4 == 1]
}
library(microbenchmark)
microbenchmark(times=10,
funSums(mat),
funApply(mat),
funRcpp(mat)
)

产生:
Unit: milliseconds
expr min lq median uq max neval
funSums(mat) 4.035823 4.079707 5.256517 7.5359 42.06529 10
funApply(mat) 379.124825 399.060015 430.899162 455.7755 471.35960 10
funRcpp(mat) 18.481184 20.364885 38.595383 106.0277 132.93382 10

并检查:
all.equal(funSums(mat), funApply(mat))
# [1] TRUE
all.equal(funSums(mat), funRcpp(mat))
# [1] TRUE

关键在于 *Sums函数完全“矢量化”,所有计算都在 C 中进行。 apply仍然需要在 R 中做一堆不严格矢量化(以原始 C 函数方式)的东西,而且速度更慢(但更灵活)。

具体到这个问题,它可能会使其速度提高 2-3 倍,因为大约一半的时间花在换位上,这只是必要的,以便 dim更改做我需要的 colSums上类。

关于r - 在 R 中的大矩阵中添加连续的四/n 个数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25534819/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com