R:具有最大值的列和行索引
R: column and row indices with largest values
假设我们有一个如下所示的矩阵:
-0.3 0.2 0.001 -0.4 0.5
0.25 0.45 0.2 -0.001 0.02
0.8 - 0.2 0.35 0.1 0.1
0.25 -0.14 -0.1 0.02 0.4
现在我想找到矩阵中尺寸为 2 x 2 且其中具有最大元素(绝对值)的那部分。
所以这里将是以下索引:
2 1
2 2
3 1
3 2
因为
0.25 0.4
0.8 -0.2
是矩阵中所有 2 x 2 矩阵中具有最大值的部分。
我如何在 R 中实现它?
我做了这个小例子,因为我的真实矩阵包含大约 4000 列和 5000 行,但这个矩阵中的许多值几乎为零。这很难形象化,因此我只想形象化最重要的部分。
您可以使用 which
来查找矩阵最大值的索引。
set.seed(1234)
mat <- matrix(sample(1:20), ncol = 5)
mat
# [,1] [,2] [,3] [,4] [,5]
# [1,] 3 14 8 20 17
# [2,] 12 10 6 15 16
# [3,] 11 1 7 2 19
# [4,] 18 4 5 9 13
which(mat == max(mat), arr.ind = TRUE)
# row col
# [1,] 1 4
如果您正在寻找每列(或行)中的最大值,您可以使用:
apply(mat, 2, which.max)
# [1] 4 1 1 1 3
问题澄清后编辑
mrow <- nrow(mat); mcol <- ncol(mat)
subs <- list()
for (i in 1:(nrow(mat) - 1)) {
for (j in 1:(ncol(mat) - 1)) {
x <- c(i, j, i, j + 1, i + 1, j, i + 1, j + 1)
subs[[paste0(i, j)]] <- matrix(x, ncol = 2, byrow = TRUE)
}
}
sums <- sapply(subs, function (x) sum(abs(mat[x])))
win <- subs[[which(sums == max(sums))]]
mat[win[1, 1]:(win[1, 1] + 1), win[1, 2]:(win[1, 2] + 1)]
# [,1] [,2]
# [1,] 20 17
# [2,] 15 16
我会很慢但是完成工作,这将给出所需子矩阵的行和列索引:
library(magrittr)
df = expand.grid(seq(nrow(mat)-1), seq(ncol(mat)-1))
vec = apply(df, 1, function(u){
mat[u[1]:(u[1]+1),u[2]:(u[2]+1)] %>%
abs %>%
sum
})
ind = df[which.max(vec),]
mat[ind[[1]]:(ind[[1]]+1),ind[[2]]:(ind[[2]]+1)]
# [,1] [,2]
#[1,] 20 17
#[2,] 15 16
其中 mat
是:
mat = structure(c(3L, 12L, 11L, 18L, 14L, 10L, 1L, 4L, 8L, 6L, 7L,
5L, 20L, 15L, 2L, 9L, 17L, 16L, 19L, 13L), .Dim = 4:5)
包 RcppRoll
提供了可能有用的快速滚动求和函数。这是一个比在大型矩阵上运行速度更快的答案:
n <- matrix(rnorm(4000*5000),nrow=4000,ncol=5000)
find_idx_max_square <- function(matrix) {
library(RcppRoll)
o <- apply(abs(matrix), 2,roll_suml,n=2L)
p <- t(apply(o, 1,roll_suml,n=2L))
idx <- which(p == max(p,na.rm=TRUE),arr.ind=TRUE)
return(idx)
}
find_idx_max_square(n)
row col
[1,] 1837 724
> system.time(find_idx_max_square(n))
utilisateur système écoulé
1.863 0.159 2.023
说明
- 取矩阵
matrix
- 计算每列所有后续两个元素的滚动总和(
matrix[i,j] + matrix[i+1,j]
for i
in nrow(matrix)
and j
in ncol(matrix)
)。将其存储在新矩阵中 o
- 计算每列每行所有后续两个元素的滚动总和(
matrix[i,j] + matrix[i,j+1]
for i
in nrow(matrix)
and j
in ncol(matrix)
).将其存储在一个新矩阵中 p
.
p
在每个单元格 [i,j]
中包含原始 [i,j]
、[i+1,j]
、[i,j+1]
、[i+1,j+1]
的值总和=12=]
- 计算
p
的最大值。它给了我们最大和的2*2子矩阵左上角值的索引。
假设我们有一个如下所示的矩阵:
-0.3 0.2 0.001 -0.4 0.5
0.25 0.45 0.2 -0.001 0.02
0.8 - 0.2 0.35 0.1 0.1
0.25 -0.14 -0.1 0.02 0.4
现在我想找到矩阵中尺寸为 2 x 2 且其中具有最大元素(绝对值)的那部分。 所以这里将是以下索引:
2 1
2 2
3 1
3 2
因为
0.25 0.4
0.8 -0.2
是矩阵中所有 2 x 2 矩阵中具有最大值的部分。
我如何在 R 中实现它?
我做了这个小例子,因为我的真实矩阵包含大约 4000 列和 5000 行,但这个矩阵中的许多值几乎为零。这很难形象化,因此我只想形象化最重要的部分。
您可以使用 which
来查找矩阵最大值的索引。
set.seed(1234)
mat <- matrix(sample(1:20), ncol = 5)
mat
# [,1] [,2] [,3] [,4] [,5]
# [1,] 3 14 8 20 17
# [2,] 12 10 6 15 16
# [3,] 11 1 7 2 19
# [4,] 18 4 5 9 13
which(mat == max(mat), arr.ind = TRUE)
# row col
# [1,] 1 4
如果您正在寻找每列(或行)中的最大值,您可以使用:
apply(mat, 2, which.max)
# [1] 4 1 1 1 3
问题澄清后编辑
mrow <- nrow(mat); mcol <- ncol(mat)
subs <- list()
for (i in 1:(nrow(mat) - 1)) {
for (j in 1:(ncol(mat) - 1)) {
x <- c(i, j, i, j + 1, i + 1, j, i + 1, j + 1)
subs[[paste0(i, j)]] <- matrix(x, ncol = 2, byrow = TRUE)
}
}
sums <- sapply(subs, function (x) sum(abs(mat[x])))
win <- subs[[which(sums == max(sums))]]
mat[win[1, 1]:(win[1, 1] + 1), win[1, 2]:(win[1, 2] + 1)]
# [,1] [,2]
# [1,] 20 17
# [2,] 15 16
我会很慢但是完成工作,这将给出所需子矩阵的行和列索引:
library(magrittr)
df = expand.grid(seq(nrow(mat)-1), seq(ncol(mat)-1))
vec = apply(df, 1, function(u){
mat[u[1]:(u[1]+1),u[2]:(u[2]+1)] %>%
abs %>%
sum
})
ind = df[which.max(vec),]
mat[ind[[1]]:(ind[[1]]+1),ind[[2]]:(ind[[2]]+1)]
# [,1] [,2]
#[1,] 20 17
#[2,] 15 16
其中 mat
是:
mat = structure(c(3L, 12L, 11L, 18L, 14L, 10L, 1L, 4L, 8L, 6L, 7L,
5L, 20L, 15L, 2L, 9L, 17L, 16L, 19L, 13L), .Dim = 4:5)
包 RcppRoll
提供了可能有用的快速滚动求和函数。这是一个比在大型矩阵上运行速度更快的答案:
n <- matrix(rnorm(4000*5000),nrow=4000,ncol=5000)
find_idx_max_square <- function(matrix) {
library(RcppRoll)
o <- apply(abs(matrix), 2,roll_suml,n=2L)
p <- t(apply(o, 1,roll_suml,n=2L))
idx <- which(p == max(p,na.rm=TRUE),arr.ind=TRUE)
return(idx)
}
find_idx_max_square(n)
row col
[1,] 1837 724
> system.time(find_idx_max_square(n))
utilisateur système écoulé
1.863 0.159 2.023
说明
- 取矩阵
matrix
- 计算每列所有后续两个元素的滚动总和(
matrix[i,j] + matrix[i+1,j]
fori
innrow(matrix)
andj
inncol(matrix)
)。将其存储在新矩阵中o
- 计算每列每行所有后续两个元素的滚动总和(
matrix[i,j] + matrix[i,j+1]
fori
innrow(matrix)
andj
inncol(matrix)
).将其存储在一个新矩阵中p
. p
在每个单元格[i,j]
中包含原始[i,j]
、[i+1,j]
、[i,j+1]
、[i+1,j+1]
的值总和=12=]- 计算
p
的最大值。它给了我们最大和的2*2子矩阵左上角值的索引。