gpt4 book ai didi

r - 将每一行的前 2 个值保留在 R 中的矩阵(或 data.frame)中的最快方法

转载 作者:行者123 更新时间:2023-12-04 10:27:39 24 4
gpt4 key购买 nike

假设我有矩阵 M,我只想保留这些矩阵中每行的 2 个最大值,其他值将设置为零。

M <- rbind(c(0.1, 0.6, 0.2, 0.3, 0.7), c(0.8, 0.1, 0.7, 0.2, 0.4))

> M
[,1] [,2] [,3] [,4] [,5]
[1,] 0.1 0.6 0.2 0.3 0.7
[2,] 0.8 0.1 0.7 0.2 0.4

我想要这个结果。

rbind(c(0, 0.6, 0, 0, 0.7), c(0.8, 0, 0.7, 0, 0))


> rbind(c(0, 0.6, 0, 0, 0.7), c(0.8, 0, 0.7, 0, 0))
[,1] [,2] [,3] [,4] [,5]
[1,] 0.0 0.6 0.0 0 0.7
[2,] 0.8 0.0 0.7 0 0.0

我理解apply(M, 1, sort)可以做到这一点,但是如果矩阵M很大,它会很慢,那么最快的方法是什么做这个?

谢谢。

最佳答案

pmax 的方法:

m <- M
x1 <- do.call(pmax, lapply(1:ncol(M), function(x) M[, x]))
m[m == x1] <- NA
x2 <- do.call(pmax, c(lapply(1:ncol(M), function(x) m[, x]), na.rm = T))
M[M != x1 & M != x2] <- 0
M

一些时间。设置一个大矩阵,然后运行其他几个建议的方法:

set.seed(1234)
M <- matrix(floor(rnorm(1e7, 100, 10)), nc = 10)
f1 <- function(M) {
m <- M
x1 <- do.call(pmax, lapply(1:ncol(M), function(x) M[, x]))
m[m == x1] <- NA
x2 <- do.call(pmax, c(lapply(1:ncol(M), function(x) m[, x]), na.rm = T))
M[M != x1 & M != x2] <- 0
M
}

f2 <- function(M) {
dt <- as.data.table(M)
dt[, grp := 1:.N]
dt <- melt(dt, id.vars = "grp")
dt_max <- dt[ dt[ order(-value), .I[c(1,2)], by = .(grp)]$V1 ]
dt[, value := 0]
dt[ dt_max, on = c("grp", "variable"), value := i.value]
as.matrix(dcast(dt, formula = grp ~ variable))
}

f3 <- function(M) {
tmp <- data.frame(row=c(row(M)), val=c(M), seq=seq_along(M))
tmp <- tmp[do.call(order,c(tmp[1:2],decreasing=TRUE)),]
M[tmp$seq] <- with(tmp, ave(val,row,FUN=function(x) replace(x, -(1:2), 0) ))
M
}

使用 microbenchmark 进行基准测试,由@SymbolixAU 提出:

microbenchmark::microbenchmark(
f1 = { f1(M) },
f2 = { f2(M) },
f3 = { f3(M) },
times = 10L)
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# f1 926.9069 946.6892 1084.038 1009.497 1082.454 1476.972 10 a
# f2 6315.3971 6750.1864 7327.610 7237.323 7785.078 9198.780 10 b
# f3 13076.0617 13435.9920 15360.451 15118.323 16497.295 19792.398 10 c

此外,如果给定行的最大两个数字有重复项,其他方法似乎会将重复项设置为零。

关于r - 将每一行的前 2 个值保留在 R 中的矩阵(或 data.frame)中的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42126955/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com