gpt4 book ai didi

r - 如何将矩阵的每一行除以R中向量的元素

转载 作者:行者123 更新时间:2023-12-03 05:49:30 25 4
gpt4 key购买 nike

我想将矩阵的每一除以一个固定向量。例如

mat<-matrix(1,ncol=2,nrow=2,TRUE)
dev<-c(5,10)

给出mat/dev将每个除以dev

     [,1] [,2]
[1,] 0.2 0.2
[2,] 0.1 0.1

但是,我希望得到这样的结果,即按行进行操作:

rbind(mat[1,]/dev, mat[2,]/dev)

[,1] [,2]
[1,] 0.2 0.1
[2,] 0.2 0.1

是否有明确的命令可以到达那里?

最佳答案

以下是按顺序增加代码长度的几种方法:

t(t(mat) / dev)

mat / dev[col(mat)] # @DavidArenburg & @akrun

mat %*% diag(1 / dev)

sweep(mat, 2, dev, "/")

t(apply(mat, 1, "/", dev))

plyr::aaply(mat, 1, "/", dev)

mat / rep(dev, each = nrow(mat))

mat / t(replace(t(mat), TRUE, dev))

mapply("/", as.data.frame(mat), dev) # added later

mat / matrix(dev, nrow(mat), ncol(mat), byrow = TRUE) # added later

do.call(rbind, lapply(as.data.frame(t(mat)), "/", dev))

mat2 <- mat; for(i in seq_len(nrow(mat2))) mat2[i, ] <- mat2[i, ] / dev

数据框

如果 mat 是数据帧并生成数据帧结果,则以 mat/ 开头的所有解决方案也都有效。 sweep 解决方案和最后一个解决方案(即 mat2)的情况也是如此。 mapply 解决方案适用于 data.frames,但会生成一个矩阵。

矢量

如果mat是一个普通向量而不是矩阵,那么它们中的任何一个都会返回一个单列矩阵

t(t(mat) / dev)
mat / t(replace(t(mat), TRUE, dev))

这个返回一个向量:

plyr::aaply(mat, 1, "/", dev)

其他人给出错误、警告或不是所需的答案。

基准

代码的简洁性和清晰度可能比速度更重要,但为了完整性,这里有一些使用 10 次重复和 100 次重复的基准测试。

library(microbenchmark)
library(plyr)

set.seed(84789)

mat<-matrix(runif(1e6),nrow=1e5)
dev<-runif(10)

microbenchmark(times=10L,
"1" = t(t(mat) / dev),
"2" = mat %*% diag(1/dev),
"3" = sweep(mat, 2, dev, "/"),
"4" = t(apply(mat, 1, "/", dev)),
"5" = mat / rep(dev, each = nrow(mat)),
"6" = mat / t(replace(t(mat), TRUE, dev)),
"7" = aaply(mat, 1, "/", dev),
"8" = do.call(rbind, lapply(as.data.frame(t(mat)), "/", dev)),
"9" = {mat2 <- mat; for(i in seq_len(nrow(mat2))) mat2[i, ] <- mat2[i, ] / dev},
"10" = mat/dev[col(mat)])

给予:

Unit: milliseconds
expr min lq mean median uq max neval
1 7.957253 8.136799 44.13317 8.370418 8.597972 366.24246 10
2 4.678240 4.693771 10.11320 4.708153 4.720309 58.79537 10
3 15.594488 15.691104 16.38740 15.843637 16.559956 19.98246 10
4 96.616547 104.743737 124.94650 117.272493 134.852009 177.96882 10
5 17.631848 17.654821 18.98646 18.295586 20.120382 21.30338 10
6 19.097557 19.365944 27.78814 20.126037 43.322090 48.76881 10
7 8279.428898 8496.131747 8631.02530 8644.798642 8741.748155 9194.66980 10
8 509.528218 524.251103 570.81573 545.627522 568.929481 821.17562 10
9 161.240680 177.282664 188.30452 186.235811 193.250346 242.45495 10
10 7.713448 7.815545 11.86550 7.965811 8.807754 45.87518 10

对所有花费 <20 毫秒并重复 100 次的测试重新运行测试:

microbenchmark(times=100L,
"1" = t(t(mat) / dev),
"2" = mat %*% diag(1/dev),
"3" = sweep(mat, 2, dev, "/"),
"5" = mat / rep(dev, each = nrow(mat)),
"6" = mat / t(replace(t(mat), TRUE, dev)),
"10" = mat/dev[col(mat)])

给予:

Unit: milliseconds
expr min lq mean median uq max neval
1 8.010749 8.188459 13.972445 8.560578 10.197650 299.80328 100
2 4.672902 4.734321 5.802965 4.769501 4.985402 20.89999 100
3 15.224121 15.428518 18.707554 15.836116 17.064866 42.54882 100
5 17.625347 17.678850 21.464804 17.847698 18.209404 303.27342 100
6 19.158946 19.361413 22.907115 19.772479 21.142961 38.77585 100
10 7.754911 7.939305 9.971388 8.010871 8.324860 25.65829 100

因此,在这两个测试中,#2(使用 diag)是最快的。原因可能在于它几乎直接吸引 BLAS,而#1 则依赖于成本更高的t

关于r - 如何将矩阵的每一行除以R中向量的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20596433/

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