【发布时间】:2013-03-13 18:12:42
【问题描述】:
所以我试图对矩阵的行求和,其中有 inf。如何对行求和,省略 inf?
【问题讨论】:
-
我很震惊没有人问过传统的 StackOverflow 问题:“你试过什么?”
-
我对 +9 感到震惊(到目前为止)。 Upvote 明确指出 这个问题显示了研究工作
所以我试图对矩阵的行求和,其中有 inf。如何对行求和,省略 inf?
【问题讨论】:
将您的矩阵乘以is.finite(m) 的结果,然后在具有na.rm=TRUE 的乘积上调用rowSums。这是因为Inf*0 是NaN。
m <- matrix(c(1:3,Inf,4,Inf,5:6),4,2)
rowSums(m*is.finite(m),na.rm=TRUE)
【讨论】:
A[is.infinite(A)]<-NA
rowSums(A,na.rm=TRUE)
一些基准比较:
library(microbenchmark)
rowSumsMethod<-function(A){
A[is.infinite(A)]<-NA
rowSums(A,na.rm=TRUE)
}
applyMethod<-function(A){
apply( A , 1 , function(x){ sum(x[!is.infinite(x)])})
}
rowSumsMethod2<-function(m){
rowSums(m*is.finite(m),na.rm=TRUE)
}
rowSumsMethod0<-function(A){
A[is.infinite(A)]<-0
rowSums(A)
}
A1 <- matrix(sample(c(1:5, Inf), 50, TRUE), ncol=5)
A2 <- matrix(sample(c(1:5, Inf), 5000, TRUE), ncol=5)
microbenchmark(rowSumsMethod(A1),rowSumsMethod(A2),
rowSumsMethod0(A1),rowSumsMethod0(A2),
rowSumsMethod2(A1),rowSumsMethod2(A2),
applyMethod(A1),applyMethod(A2))
Unit: microseconds
expr min lq median uq max neval
rowSumsMethod(A1) 13.063 14.9285 16.7950 19.3605 1198.450 100
rowSumsMethod(A2) 212.726 220.8905 226.7220 240.7165 307.427 100
rowSumsMethod0(A1) 11.663 13.9960 15.3950 18.1940 112.894 100
rowSumsMethod0(A2) 103.098 109.6290 114.0610 122.9240 159.545 100
rowSumsMethod2(A1) 8.864 11.6630 12.5960 14.6955 49.450 100
rowSumsMethod2(A2) 57.380 60.1790 63.4450 67.4100 81.172 100
applyMethod(A1) 78.839 84.4380 92.1355 99.8330 181.005 100
applyMethod(A2) 3996.543 4221.8645 4338.0235 4552.3825 6124.735 100
所以约书亚的方法赢了!而且 apply 方法显然比其他两种方法慢(当然相对而言)。
【讨论】:
!is.infinite()合二为一!
sums <- apply( A , 1 , FUN = function(x){ sum(x[!is.infinite(x)])})
0替换并留下na.rm=FALSE,这样可能会更快。
我会使用 apply 和 is.infinite 以避免将 Inf 值替换为 @Hemmo 的答案中的 NA。
> set.seed(1)
> Mat <- matrix(sample(c(1:5, Inf), 50, TRUE), ncol=5)
> Mat # this is an example
[,1] [,2] [,3] [,4] [,5]
[1,] 2 2 Inf 3 5
[2,] 3 2 2 4 4
[3,] 4 5 4 3 5
[4,] Inf 3 1 2 4
[5,] 2 5 2 5 4
[6,] Inf 3 3 5 5
[7,] Inf 5 1 5 1
[8,] 4 Inf 3 1 3
[9,] 4 3 Inf 5 5
[10,] 1 5 3 3 5
> apply(Mat, 1, function(x) sum(x[!is.infinite(x)]))
[1] 12 15 21 10 18 16 12 11 17 17
【讨论】:
试试这个...
m <- c( 1 ,2 , 3 , Inf , 4 , Inf ,5 )
sum(m[!is.infinite(m)])
或者
m <- matrix( sample( c(1:10 , Inf) , 100 , rep = TRUE ) , nrow = 10 )
sums <- apply( m , 1 , FUN = function(x){ sum(x[!is.infinite(x)])})
> m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 8 9 7 Inf 9 2 2 6 1 Inf
[2,] 8 7 4 5 9 5 8 4 7 10
[3,] 7 9 3 4 7 3 3 6 9 4
[4,] 7 Inf 2 6 4 8 3 1 9 9
[5,] 4 Inf 7 5 9 5 3 5 9 9
[6,] 7 3 7 Inf 7 3 7 3 7 1
[7,] 5 7 2 1 Inf 1 9 8 1 5
[8,] 4 Inf 10 Inf 8 10 4 9 7 2
[9,] 10 7 9 7 2 Inf 4 Inf 4 6
[10,] 9 4 6 3 9 6 6 5 1 8
> sums
[1] 44 67 55 49 56 45 39 54 49 57
【讨论】:
这是一种“非应用”且非破坏性的方法:
rowSums( matrix(match(A, A[is.finite(A)]), nrow(A)), na.rm=TRUE)
[1] 2 4
虽然效率相当高,但不如 Johsua 的乘法方法快。
【讨论】:
match(A, A[is.finite(A)])。我已经编辑过了。希望你不要介意。
A[is.finite(A)] 替换了is.finite(A)。没有这个,match 会吐出所有的 NA,因为它匹配所有值为 TRUE 的值。因此,只有值 1 将与 TRUE 匹配。其他所有值都将获得 NA。