2

如果条目大于零,我需要将矩阵中的每个条目除以 1。我目前使用以下(1.除法。2.将 Inf 转换为零),但它工作非常缓慢,而且矩阵很大。

wii <- 1/wii
wii[is.infinite(wii)] <- 0

你能建议如何优化吗?我认为使用 mapply 为每个条目应用该函数应该可以工作,但我不知道在这种情况下如何使用条件。感谢您的建议!

# example

0   0   0   0   1000
0   100 0   0   0
0   0   0   0   0
0   0   0   10  0
0   0   0   0   0
1   0   10  0   0
0   0   0   0   0
4

2 回答 2

3

这会更快一些:

wii <- 1/(1/(1-1/(wii == 0)) + wii)

更好的是(而且更简单!)是评论中的@sgibb 版本(对于大多数为 0 的矩阵来说它会更好):

tmp <- which(wii != 0)
wii[tmp] <- 1/wii[tmp];

基准:

N = 1e3

wii = matrix(sample(c(0, 10), N*N, T), nrow = N)

op = function(wii) {
  wii <- 1/wii
  wii[is.infinite(wii)] <- 0
}

so = function(wii) {
  tmp <- wii != 0     # doing this is faster than Señor O's original answer
  wii[tmp] <- 1/wii[tmp]
}

ed = function(wii) {
  wii <- 1/(1/(1-1/(wii == 0)) + wii)
}

sg = function(wii) {
  tmp <- which(wii != 0)
  wii[tmp] <- 1/wii[tmp];
}

require(microbenchmark)
microbenchmark(op(wii), so(wii), ed(wii), sg(wii), times = 100)
#Unit: milliseconds
#    expr      min        lq    median        uq       max neval
# op(wii) 47.91634  64.51116  76.39793  88.13995 125.72246   100
# so(wii) 82.00116 114.90850 133.25893 150.97547 196.63302   100
# ed(wii) 26.80661  41.64416  66.26577  79.08794 130.08377   100
# sg(wii) 30.86709  43.68241  50.01369  61.89294  97.65006   100
于 2013-08-12T16:41:03.550 回答
1

我认为您的订单是问题所在。为什么要对要转换为零的元素进行除法?

wii[wii!=0] <- 1/wii[wii!=0]

编辑

问题是那wii是 adata.frame而不是matrix. 矩阵运算要快得多,而且索引df[df==...]显然不起作用。

如果矩阵上的实际操作花费太多时间,上述解决方案只会提高性能 - 在这种情况下它们不会。

于 2013-08-12T16:16:06.493 回答