给定一个矩阵,比如 m,是否有任何直接方法可以找到 m 的前 k 个值,然后准确找到它们属于哪一列/行。我在 SO 上找不到任何内容,因此提出了这个问题。 我对上面的尝试是这样的:
set.seed(1729)
k=5 #top 5
m = matrix(round(runif(30),digits = 2),nr=10)
idx <- which(matrix(m %in% head(sort(m), k), nr = nrow(m)), arr.ind = TRUE)
print(m)
[,1] [,2] [,3]
[1,] 0.59 0.54 0.57
[2,] 0.44 0.43 0.32
[3,] 0.57 0.08 0.29
[4,] 0.35 0.58 0.24
[5,] 0.86 0.52 0.53
[6,] 0.41 0.78 0.17
[7,] 0.51 0.47 0.26
[8,] 0.15 0.81 0.49
[9,] 0.85 0.64 0.64
[10,] 1.00 0.78 0.95
print(idx)
row col
[1,] 8 1
[2,] 3 2
[3,] 4 3
[4,] 6 3
[5,] 7 3
我不确定这是否有效,因为我正在对矩阵的整个值进行排序而不是选取那些 k 值。我想假设 k << length(m)。 对于大型矩阵 m 是否有任何有效的方法,以及在某些情况下是否可以帮助我处理重复,例如当一个人想要获得前 k 列名称时
例如:对于矩阵 mm,我需要确定具有最小值的前 2 列。在这里,对于以下情况,我期待第 1 列和第 2 列
mm = matrix(c(6,6,7,8,7,9,8,8,9), 3)
print(mm)
[,1] [,2] [,3]
[1,] 6 8 8
[2,] 6 7 8
[3,] 7 9 9
idx <- which(matrix(mm %in% head(sort(mm), 2), nr = nrow(mm)), arr.ind = TRUE)
print(idx)
row col
[1,] 1 1
[2,] 2 1
但是,在这里我只有一列,即; 1,在这种情况下,输出应该是具有最小值的两个不同列,即。 1 和 2
最佳答案
这是对 OP 方法的比较,@Barker 的替代 R 的部分排序功能的建议以及使用 quantile
的方法:
# example data
set.seed(1729)
n = 1e6
k = 50
m = matrix(runif(n), nr=10)
# illustration of the quantile way
which(m <= quantile(m, k/length(m)), arr.ind = TRUE)
# or...
library(data.table)
setDT(melt(m))[ value <= quantile(value, k/.N) ]
# Var1 Var2 value
# 1: 8 4945 1.471722e-06
# 2: 1 7025 1.856475e-05
# 3: 9 7480 4.518987e-05
# 4: 10 8378 1.877453e-05
# 5: 2 9043 3.262958e-05
# 6: 7 9925 1.327880e-05
# 7: 5 13571 5.097035e-05
# ...
# benchmark
microbenchmark::microbenchmark(times = 30,
idx = idx <- which(matrix(m %in% head(sort(m), k), nr = nrow(m)), arr.ind = TRUE),
dtq = dtq <- setDT(melt(m))[ value <= quantile(value, k/.N) ],
idxp = idxp <- which(matrix(m %in% head(sort(m, partial = 1:k), k), nr = nrow(m)), arr.ind = TRUE),
idxq = idxq <- which(m <= quantile(m, k/length(m)), arr.ind = TRUE)
)
# verifying, requires data.table 1.9.7+
fsetequal(as.data.table(idx), dtq[, .(row = Var1, col = Var2)])
fsetequal(as.data.table(idxp), dtq[, .(row = Var1, col = Var2)])
fsetequal(as.data.table(idxq), dtq[, .(row = Var1, col = Var2)])
给出
Unit: milliseconds
expr min lq mean median uq max neval cld
idx 145.01260 148.10571 155.27124 149.97761 152.45523 206.27179 30 d
dtq 30.05910 33.11280 44.83088 35.02334 37.78721 90.92545 30 b
idxp 114.69501 118.23185 127.37992 119.50131 121.33241 175.41117 30 c
idxq 13.02406 14.47907 22.81266 16.41707 18.28308 68.53364 30 a
我为这个例子去掉了 OP 的四舍五入。调整参数 n
和 k
可能会导致不同的方法排名。我的首选方法是 setDT(melt(m))[order(value, partial = 1:k)]
但它看起来在 R 中尚不可用。
关于r - 如何有效地找到矩阵前 n 个值的列索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40669687/