which(x,arr.ind=T)
我在 Rcpp 或 RcppArmadillo 中找不到很酷的功能。所以我决定自己快速编写代码。
// [[Rcpp::export]]
arma::umat whicha(arma::mat matrix, int what ){
arma::uvec outp1;
int n = matrix.n_rows;
outp1 = find(matrix==what);
int nf = outp1.n_elem;
arma::mat out(nf,2);
arma::vec foo;
arma::uvec foo2;
foo = arma::conv_to<arma::colvec>::from(outp1) +1;
foo2 = arma::conv_to<arma::uvec>::from(foo);
for(int i=0; i<nf; i++){
out(i,0) = ( foo2(i) %n);
out(i,1) = ceil(foo(i) / n );
if(out(i,0)==0) {
out(i,0)=n;
}
}
return(arma::conv_to<arma::umat>::from(out));
}
该代码似乎效率很低,但microbenchmark
表明它可以比 R 的which
函数更快。
问题:我可以进一步改变这个函数来真正准确地重现 R 的which
函数,即传递MATRIX == something
给它吗?现在我需要第二个论点。我只是为了方便而喜欢这个。
更新:修复了一个错误 - 需要 ceil 而不是 floor
如何检查:
ma=floor(abs(rnorm(100,0,6)))
testf=function(k) {all(which(ma==k,arr.ind=T) == whicha(ma,k))} ; sapply(1:10,testf)
基准:
> microbenchmark(which(ma==k,arr.ind=T) , whicha(ma,k))
Unit: microseconds
expr min lq median uq max neval
which(ma == k, arr.ind = T) 10.264 11.170 11.774 12.377 51.317 100
whicha(ma, k) 3.623 4.227 4.830 5.133 36.224 100