R:数组 - 减少长度(泛化)
R: arrays - reducing length (generalization)
我需要在 R 中减少长度(泛化)数组。例如,我有这样的高分辨率数据...
my_array=array(c(sample(0:9,32, replace=TRUE)), dim=c(4,4,2))
> my_array
, , 1
[,1] [,2] [,3] [,4]
[1,] 2 1 8 2
[2,] 3 5 4 6
[3,] 2 8 9 6
[4,] 1 0 9 9
, , 2
[,1] [,2] [,3] [,4]
[1,] 3 7 9 7
[2,] 9 4 9 8
[3,] 8 6 7 8
[4,] 7 6 9 9
...我需要 "generalise" 使用 mean 函数将其设为低分辨率,如下所示:
, , 1
[,1] [,2]
[1,] 2.75 4.00
[2,] 2.75 8.25
, , 2
[,1] [,2]
[1,] 5.75 8.25
[2,] 6.75 8.25
简单地说,原始数组的4个值(位置[1,1];[1,2];[2,1];[2,2])在结果数组中形成1个值(平均值)[ 1,1] 位置。我试过在数组上使用 "apply",但我无法处理 "non-standard" 边距。有没有更复杂的函数,比如R中的apply?
我想对此发表评论,但我没有足够的声誉来发表评论,所以我 post 在这里发表评论。
我找到了一个类似的问答 here。
根据我找到的答案,您的问题的解决方案可能是:
my_array=array(c(sample(0:9,32, replace=TRUE)), dim=c(4,4,2))
my_array
rmean <- array(c(matrix(0,2,2),matrix(0,2,2)),dim=c(2,2,2)) # result array
for (i in 1:2){
for (j in 1:2){
for (k in 1:2){
rmean[,,k][i, j] <- mean(my_array[,,k][c(-1,0) + 2 * i, c(-1,0) + 2 * j])
}
}
}
rmean
结果:
> my_array
, , 1
[,1] [,2] [,3] [,4]
[1,] 8 4 4 9
[2,] 0 7 9 5
[3,] 2 7 2 6
[4,] 9 5 8 6
, , 2
[,1] [,2] [,3] [,4]
[1,] 2 1 4 7
[2,] 3 7 0 6
[3,] 2 8 9 3
[4,] 7 9 1 9
> rmean
, , 1
[,1] [,2]
[1,] 4.75 6.75
[2,] 5.75 5.50
, , 2
[,1] [,2]
[1,] 3.25 4.25
[2,] 6.50 5.50
这是一个与@crwang 改编的解决方案非常相似但概括为一个函数的解决方案:
reduceMatrix <- function(x, rown, coln, fun = mean, ...) {
out <- matrix(NA, nrow=nrow(x)/rown, ncol=ncol(x)/coln)
for (i in 1:(nrow(x)/rown)) {
for (j in 1:(ncol(x)/coln)) {
indi <- c(rown*i-1, rown*i)
indj <- c(coln*j-1, coln*j)
out[i, j] <- fun(x[indi, indj], ...)
}
}
out
}
该函数适用于二维数组,因此您可以将它们应用于 my_array
的第 3 个维度:
set.seed(10)
my_array <- array(c(sample(0:9,32, replace=TRUE)), dim=c(4,4,2))
lapply(seq_len(dim(my_array)[3]),
function(a) reduceMatrix(my_array[,,a], 2, 2))
[[1]]
[,1] [,2]
[1,] 2.5 4.0
[2,] 3.5 4.5
[[2]]
[,1] [,2]
[1,] 4.00 5.25
[2,] 5.25 3.75
这种方法的想法是有一个函数既可以用于独立矩阵(在 3D 数组、列表等中),也可以更容易地选择行数 (rown
) 和列数 ( coln
) 以及应用函数 (mean
、median
、sum
) 和其他参数(例如 na.rm
)。
我需要在 R 中减少长度(泛化)数组。例如,我有这样的高分辨率数据...
my_array=array(c(sample(0:9,32, replace=TRUE)), dim=c(4,4,2))
> my_array
, , 1
[,1] [,2] [,3] [,4]
[1,] 2 1 8 2
[2,] 3 5 4 6
[3,] 2 8 9 6
[4,] 1 0 9 9
, , 2
[,1] [,2] [,3] [,4]
[1,] 3 7 9 7
[2,] 9 4 9 8
[3,] 8 6 7 8
[4,] 7 6 9 9
...我需要 "generalise" 使用 mean 函数将其设为低分辨率,如下所示:
, , 1
[,1] [,2]
[1,] 2.75 4.00
[2,] 2.75 8.25
, , 2
[,1] [,2]
[1,] 5.75 8.25
[2,] 6.75 8.25
简单地说,原始数组的4个值(位置[1,1];[1,2];[2,1];[2,2])在结果数组中形成1个值(平均值)[ 1,1] 位置。我试过在数组上使用 "apply",但我无法处理 "non-standard" 边距。有没有更复杂的函数,比如R中的apply?
我想对此发表评论,但我没有足够的声誉来发表评论,所以我 post 在这里发表评论。
我找到了一个类似的问答 here。
根据我找到的答案,您的问题的解决方案可能是:
my_array=array(c(sample(0:9,32, replace=TRUE)), dim=c(4,4,2))
my_array
rmean <- array(c(matrix(0,2,2),matrix(0,2,2)),dim=c(2,2,2)) # result array
for (i in 1:2){
for (j in 1:2){
for (k in 1:2){
rmean[,,k][i, j] <- mean(my_array[,,k][c(-1,0) + 2 * i, c(-1,0) + 2 * j])
}
}
}
rmean
结果:
> my_array
, , 1
[,1] [,2] [,3] [,4]
[1,] 8 4 4 9
[2,] 0 7 9 5
[3,] 2 7 2 6
[4,] 9 5 8 6
, , 2
[,1] [,2] [,3] [,4]
[1,] 2 1 4 7
[2,] 3 7 0 6
[3,] 2 8 9 3
[4,] 7 9 1 9
> rmean
, , 1
[,1] [,2]
[1,] 4.75 6.75
[2,] 5.75 5.50
, , 2
[,1] [,2]
[1,] 3.25 4.25
[2,] 6.50 5.50
这是一个与@crwang 改编的解决方案非常相似但概括为一个函数的解决方案:
reduceMatrix <- function(x, rown, coln, fun = mean, ...) {
out <- matrix(NA, nrow=nrow(x)/rown, ncol=ncol(x)/coln)
for (i in 1:(nrow(x)/rown)) {
for (j in 1:(ncol(x)/coln)) {
indi <- c(rown*i-1, rown*i)
indj <- c(coln*j-1, coln*j)
out[i, j] <- fun(x[indi, indj], ...)
}
}
out
}
该函数适用于二维数组,因此您可以将它们应用于 my_array
的第 3 个维度:
set.seed(10)
my_array <- array(c(sample(0:9,32, replace=TRUE)), dim=c(4,4,2))
lapply(seq_len(dim(my_array)[3]),
function(a) reduceMatrix(my_array[,,a], 2, 2))
[[1]]
[,1] [,2]
[1,] 2.5 4.0
[2,] 3.5 4.5
[[2]]
[,1] [,2]
[1,] 4.00 5.25
[2,] 5.25 3.75
这种方法的想法是有一个函数既可以用于独立矩阵(在 3D 数组、列表等中),也可以更容易地选择行数 (rown
) 和列数 ( coln
) 以及应用函数 (mean
、median
、sum
) 和其他参数(例如 na.rm
)。