从矩阵中提取子矩阵
Extract submatrix from matrix
我在 R 中创建了一个 10x10 的矩阵(10 行和 10 列):
matriz <- matrix(1:100, nrow = 10, ncol = 10, byrow=T)
我想从矩阵 (matriz) 中随机且不重叠地提取方形子矩阵 (3x3)。
我在 R 中看到一个名为“subset.matrix”的包,但我不能随机矩阵。
有什么建议吗?
我同意 user2974951 关于随机性的评论。但是,此代码块将按照您的要求执行。
matriz <- matrix(1:100, nrow = 10, ncol = 10, byrow=T)
attempts <- 50
# Initialize a list to hold the results
sub_mats <- vector(mode = "list", length = attempts)
# The top left corner of the matrix can't have an index > 8
rand_x <- sample(1:8, attempts, replace = T)
rand_y <- sample(1:8, attempts, replace = T)
for (i in 1:attempts) {
# Get the three-length vectors
x_range <- rand_x[i] : (rand_x[i] + 2)
y_range <- rand_y[i] : (rand_y[i] + 2)
# Subset the matrix
sub_mat <- matriz[x_range, y_range]
# We'll use NAs to mark submatrices from previous loops
if (any(is.na(sub_mat))) next
# If there's no overlap, add it to the list
sub_mats[[i]] <- sub_mat
# Set this submatrix as NAs
matriz[x_range, y_range] <- rep(NA, 9)
}
# Remove failed attempts
sub_mats <- sub_mats[!sapply(sub_mats, is.null)]
您可以使用计数器,而不是设置循环尝试次数。尝试 50 次后,我得到 4-6 个子矩阵。 1000 给出 6-8.
你可以定义如下函数f
f <- function(mat, submat.size = 3) {
ridx <- Filter(function(x) length(x) == submat.size, split(sample(seq(nrow(mat))), ceiling(seq(nrow(mat)) / submat.size)))
cidx <- Filter(function(x) length(x) == submat.size, split(sample(seq(ncol(mat))), ceiling(seq(ncol(mat)) / submat.size)))
replicate(2, mat[ridx[[sample(length(ridx), 1)]], cidx[[sample(length(cidx), 1)]]], simplify = FALSE)
}
并且此函数使您能够生成一对子矩阵,它们是 random 和 非重叠.
示例结果
> f(matriz)
[[1]]
[,1] [,2] [,3]
[1,] 68 67 70
[2,] 38 37 40
[3,] 88 87 90
[[2]]
[,1] [,2] [,3]
[1,] 63 62 69
[2,] 33 32 39
[3,] 83 82 89
如果每次都想要所有可能的独占随机子矩阵,可以试试
f2 <- function(mat, submat.size = 3) {
ridx <- Filter(function(x) length(x) == submat.size, split(sample(seq(nrow(mat))), ceiling(seq(nrow(mat)) / submat.size)))
cidx <- Filter(function(x) length(x) == submat.size, split(sample(seq(ncol(mat))), ceiling(seq(ncol(mat)) / submat.size)))
r <- list()
for (i in seq_along(ridx)) {
for (j in seq_along(cidx)) {
r[[length(r) + 1]] <- mat[ridx[[i]], cidx[[j]]]
}
}
r
}
你将获得
> f2(matriz)
[[1]]
[,1] [,2] [,3]
[1,] 3 6 5
[2,] 63 66 65
[3,] 83 86 85
[[2]]
[,1] [,2] [,3]
[1,] 2 8 4
[2,] 62 68 64
[3,] 82 88 84
[[3]]
[,1] [,2] [,3]
[1,] 1 10 7
[2,] 61 70 67
[3,] 81 90 87
[[4]]
[,1] [,2] [,3]
[1,] 13 16 15
[2,] 33 36 35
[3,] 23 26 25
[[5]]
[,1] [,2] [,3]
[1,] 12 18 14
[2,] 32 38 34
[3,] 22 28 24
[[6]]
[,1] [,2] [,3]
[1,] 11 20 17
[2,] 31 40 37
[3,] 21 30 27
[[7]]
[,1] [,2] [,3]
[1,] 43 46 45
[2,] 53 56 55
[3,] 73 76 75
[[8]]
[,1] [,2] [,3]
[1,] 42 48 44
[2,] 52 58 54
[3,] 72 78 74
[[9]]
[,1] [,2] [,3]
[1,] 41 50 47
[2,] 51 60 57
[3,] 71 80 77
我在 R 中创建了一个 10x10 的矩阵(10 行和 10 列):
matriz <- matrix(1:100, nrow = 10, ncol = 10, byrow=T)
我想从矩阵 (matriz) 中随机且不重叠地提取方形子矩阵 (3x3)。
我在 R 中看到一个名为“subset.matrix”的包,但我不能随机矩阵。
有什么建议吗?
我同意 user2974951 关于随机性的评论。但是,此代码块将按照您的要求执行。
matriz <- matrix(1:100, nrow = 10, ncol = 10, byrow=T)
attempts <- 50
# Initialize a list to hold the results
sub_mats <- vector(mode = "list", length = attempts)
# The top left corner of the matrix can't have an index > 8
rand_x <- sample(1:8, attempts, replace = T)
rand_y <- sample(1:8, attempts, replace = T)
for (i in 1:attempts) {
# Get the three-length vectors
x_range <- rand_x[i] : (rand_x[i] + 2)
y_range <- rand_y[i] : (rand_y[i] + 2)
# Subset the matrix
sub_mat <- matriz[x_range, y_range]
# We'll use NAs to mark submatrices from previous loops
if (any(is.na(sub_mat))) next
# If there's no overlap, add it to the list
sub_mats[[i]] <- sub_mat
# Set this submatrix as NAs
matriz[x_range, y_range] <- rep(NA, 9)
}
# Remove failed attempts
sub_mats <- sub_mats[!sapply(sub_mats, is.null)]
您可以使用计数器,而不是设置循环尝试次数。尝试 50 次后,我得到 4-6 个子矩阵。 1000 给出 6-8.
你可以定义如下函数f
f <- function(mat, submat.size = 3) {
ridx <- Filter(function(x) length(x) == submat.size, split(sample(seq(nrow(mat))), ceiling(seq(nrow(mat)) / submat.size)))
cidx <- Filter(function(x) length(x) == submat.size, split(sample(seq(ncol(mat))), ceiling(seq(ncol(mat)) / submat.size)))
replicate(2, mat[ridx[[sample(length(ridx), 1)]], cidx[[sample(length(cidx), 1)]]], simplify = FALSE)
}
并且此函数使您能够生成一对子矩阵,它们是 random 和 非重叠.
示例结果
> f(matriz)
[[1]]
[,1] [,2] [,3]
[1,] 68 67 70
[2,] 38 37 40
[3,] 88 87 90
[[2]]
[,1] [,2] [,3]
[1,] 63 62 69
[2,] 33 32 39
[3,] 83 82 89
如果每次都想要所有可能的独占随机子矩阵,可以试试
f2 <- function(mat, submat.size = 3) {
ridx <- Filter(function(x) length(x) == submat.size, split(sample(seq(nrow(mat))), ceiling(seq(nrow(mat)) / submat.size)))
cidx <- Filter(function(x) length(x) == submat.size, split(sample(seq(ncol(mat))), ceiling(seq(ncol(mat)) / submat.size)))
r <- list()
for (i in seq_along(ridx)) {
for (j in seq_along(cidx)) {
r[[length(r) + 1]] <- mat[ridx[[i]], cidx[[j]]]
}
}
r
}
你将获得
> f2(matriz)
[[1]]
[,1] [,2] [,3]
[1,] 3 6 5
[2,] 63 66 65
[3,] 83 86 85
[[2]]
[,1] [,2] [,3]
[1,] 2 8 4
[2,] 62 68 64
[3,] 82 88 84
[[3]]
[,1] [,2] [,3]
[1,] 1 10 7
[2,] 61 70 67
[3,] 81 90 87
[[4]]
[,1] [,2] [,3]
[1,] 13 16 15
[2,] 33 36 35
[3,] 23 26 25
[[5]]
[,1] [,2] [,3]
[1,] 12 18 14
[2,] 32 38 34
[3,] 22 28 24
[[6]]
[,1] [,2] [,3]
[1,] 11 20 17
[2,] 31 40 37
[3,] 21 30 27
[[7]]
[,1] [,2] [,3]
[1,] 43 46 45
[2,] 53 56 55
[3,] 73 76 75
[[8]]
[,1] [,2] [,3]
[1,] 42 48 44
[2,] 52 58 54
[3,] 72 78 74
[[9]]
[,1] [,2] [,3]
[1,] 41 50 47
[2,] 51 60 57
[3,] 71 80 77