如何使用R将矩阵或数据帧划分为N个大小相等的块?我想水平剪切矩阵或数据框。
例如,给定:
r = 8
c = 10
number_of_chunks = 4
data = matrix(seq(r*c), nrow = r, ncol=c)
>>> data
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 9 17 25 33 41 49 57 65 73
[2,] 2 10 18 26 34 42 50 58 66 74
[3,] 3 11 19 27 35 43 51 59 67 75
[4,] 4 12 20 28 36 44 52 60 68 76
[5,] 5 13 21 29 37 45 53 61 69 77
[6,] 6 14 22 30 38 46 54 62 70 78
[7,] 7 15 23 31 39 47 55 63 71 79
[8,] 8 16 24 32 40 48 56 64 72 80
我希望将data
剪切成4个元素的列表:
元素1:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 9 17 25 33 41 49 57 65 73
[2,] 2 10 18 26 34 42 50 58 66 74
元素2:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[3,] 3 11 19 27 35 43 51 59 67 75
[4,] 4 12 20 28 36 44 52 60 68 76
元素3:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[5,] 5 13 21 29 37 45 53 61 69 77
[6,] 6 14 22 30 38 46 54 62 70 78
元素4:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[7,] 7 15 23 31 39 47 55 63 71 79
[8,] 8 16 24 32 40 48 56 64 72 80
在python中使用numpy,我可以使用numpy.array_split
。
答案 0 :(得分:5)
这是对基地R的尝试。计算"漂亮"使用pretty
剪切行序列的值。使用cut
对行号序列进行分类,并使用split
返回切割值处的序列拆分列表。最后,使用lapply
运行分割行值列表,并使用[
提取矩阵子集。
lapply(split(seq_len(nrow(data)),
cut(seq_len(nrow(data)), pretty(seq_len(nrow(data)), number_of_chunks))),
function(x) data[x, ])
$`(0,2]`
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 9 17 25 33 41 49 57 65 73
[2,] 2 10 18 26 34 42 50 58 66 74
$`(2,4]`
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 3 11 19 27 35 43 51 59 67 75
[2,] 4 12 20 28 36 44 52 60 68 76
$`(4,6]`
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 5 13 21 29 37 45 53 61 69 77
[2,] 6 14 22 30 38 46 54 62 70 78
$`(6,8]`
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 7 15 23 31 39 47 55 63 71 79
[2,] 8 16 24 32 40 48 56 64 72 80
将其转换为函数:
array_split <- function(data, number_of_chunks) {
rowIdx <- seq_len(nrow(data))
lapply(split(rowIdx, cut(rowIdx, pretty(rowIdx, number_of_chunks))), function(x) data[x, ])
}
然后,您可以使用
array_split(data=data, number_of_chunks=number_of_chunks)
返回与上面相同的结果。
@ user20650建议的一个很好的简化是
split.data.frame(data,
cut(seq_len(nrow(data)), pretty(seq_len(nrow(data)), number_of_chunks)))
令我惊讶的是,split.data.frame
在第一个参数是矩阵时返回矩阵列表。
答案 1 :(得分:1)
number_of_chunks = 4
lapply(seq(1, NROW(data), ceiling(NROW(data)/number_of_chunks)),
function(i) data[i:min(i + ceiling(NROW(data)/number_of_chunks) - 1, NROW(data)),])
OR
lapply(split(data, rep(1:number_of_chunks, each = NROW(data)/number_of_chunks)),
function(a) matrix(a, ncol = NCOL(data)))
答案 2 :(得分:1)
尽量不要明确拆分数据,因为它是另一个副本。您宁愿拆分您想要访问的索引。
使用此功能,您可以按块数(并行度)或块大小进行拆分。
CutBySize <- function(m, block.size, nb = ceiling(m / block.size)) {
int <- m / nb
upper <- round(1:nb * int)
lower <- c(1, upper[-nb] + 1)
size <- c(upper[1], diff(upper))
cbind(lower, upper, size)
}
CutBySize(nrow(data), nb = number_of_chunks)
lower upper size
[1,] 1 2 2
[2,] 3 4 2
[3,] 5 6 2
[4,] 7 8 2