按次对角线顺序提取并排序矩阵上三角非对角线元素
按次对角线顺序提取矩阵上三角非对角线元素
刚好碰到过类似的需求!要实现按次对角线顺序提取上三角非对角线元素,核心是利用列索引减行索引的差值来分组——这个差值正好对应每条次对角线的偏移量,从1到n-1(n是矩阵的行数)。下面用你的示例矩阵来一步步实现:
首先构造示例矩阵:
A <- matrix(1:25, 5, 5) A # [,1] [,2] [,3] [,4] [,5] # [1,] 1 6 11 16 21 # [2,] 2 7 12 17 22 # [3,] 3 8 13 18 23 # [4,] 4 9 14 19 24 # [5,] 5 10 15 20 25
实现步骤
- 获取上三角非对角线元素的位置索引:用
which(upper.tri(A, diag=FALSE), arr.ind=TRUE)可以拿到所有符合条件的元素的行、列坐标。 - 计算次对角线偏移量:对每个位置,计算
列索引 - 行索引,这个值就是该元素所属的次对角线编号(比如j-i=1是第一条次对角线,j-i=2是第二条,以此类推)。 - 按偏移量分组提取元素:用
split函数按偏移量分组,就能得到你想要的按次对角线排列的列表。
具体代码如下:
n <- nrow(A) # 获取上三角非对角线元素的行、列索引 inds <- which(upper.tri(A, diag = FALSE), arr.ind = TRUE) # 计算每个元素对应的次对角线偏移量 offsets <- inds[, "col"] - inds[, "row"] # 按偏移量分组提取元素 res <- split(A[inds], offsets) # 查看结果 res # $`1` # [1] 6 12 18 24 # # $`2` # [1] 11 17 23 # # $`3` # [1] 16 22 # # $`4` # [1] 21
如果你需要把结果合并成一个单一向量(就像你示例里写的c(c(6,12,18,24), c(11,17,23), c(16,22), c(21))),只需要用unlist(res),如果不需要自动生成的名字,可以再加unname():
unname(unlist(res)) # [1] 6 12 18 24 11 17 23 16 22 21
效率说明
这个方法完全基于R的向量化操作,没有显式循环,就算是处理维度很大的矩阵(比如1000×1000)也能高效运行,因为which和split都是内置的高效函数。
内容的提问来源于stack exchange,提问作者yliueagle




