如何更快速地获取数据集中每个点到其他点的平均曼哈顿距离

时间:2019-02-25 12:14:52

标签: r

我想更快速地获取同一数据集中每个点到其他点的平均曼哈顿距离:我们可以使用函数dist()来获取距离矩阵,但是它的空间复杂度太高了,以避免这样,我的代码如下:d是数据集,d的每一列都是一个点,点到其他点的平均曼哈顿距离记录在向量a中,想要最后得到向量a

d <- matrix(rnorm(100000), nrow = 2)
s <- ncol(d)
a <- vector("numeric", s)
for (i in 1:s)
{
  L1 <- abs(d[, i ] - d)
  a[i] <- sum(L1) / s
}

3 个答案:

答案 0 :(得分:0)

下面是我的Rcpp代码,但比R代码要慢:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector DSS_Rcpp(NumericMatrix d) {
  int nc=d.ncol();
  int nr=d.nrow();  
  NumericVector a (nc);
  NumericVector v (nc*nr);
  for(int i=0; i<nc; ++i){
    v=rep(d( _ , i ),nc);
    v.attr("dim") = Dimension(nr, nc);
    a(i)=sum(abs(v-d));
  }
  return a;
}


/*** R
set.seed(0)
d <- matrix(rnorm(10000), nrow = 2)


DSS <- function(d) {
  s <- ncol(d)
  a <- vector("numeric", s)
  for (i in 1:s)
  {
    L1 <- abs(d[, i ] - d)
    a[i] <- sum(L1)
  }
  return(a)
}

library(microbenchmark)

microbenchmark(
  a1 <- DSS(d),
  a2 <- DSS_Rcpp(d),
  times = 10L
)

  */

Unit: milliseconds
           expr      min       lq       mean   median     uq      max    neval cld 

      a1 <- DSS(d) 149.0534 150.8763 162.4359 151.4906 152.5008 249.0534    10  a 

 a2 <- DSS_Rcpp(d) 432.9250 433.5424 434.9274 434.2949 435.8276 438.6070    10   b

答案 1 :(得分:0)

我在Rcpp循环中做了一些更改,虽然比较容易,但是速度却不能提高很多。

self.navigationController.viewControllers

单位:毫秒

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]

NumericVector DSS_Rcpp(NumericMatrix d) {
  int nc=d.ncol();
  NumericVector a (nc);
  for(int i=0; i<nc; ++i){
    a(i)=sum(abs(rep(d( _ , i ),nc)-d));
  }
  return a;
}


/*** R
set.seed(0)
d <- matrix(rnorm(10000), nrow = 2)


DSS <- function(d) {
  s <- ncol(d)
  a <- vector("numeric", s)
  for (i in 1:s)
  {
    L1 <- abs(d[, i ] - d)
    a[i] <- sum(L1)
  }
  return(a)
}

library(microbenchmark)

microbenchmark(
  a1 <- DSS(d),
  a2 <- DSS_Rcpp(d),
  times = 10L
)

  */

答案 2 :(得分:0)

我得到了另一种方法-使用“ purrr”软件包,但是它仍然有点慢

set.seed(0)
d <- matrix(rnorm(10000), nrow = 2)

DSS <- function(d) {
  s <- ncol(d)
  a <- vector("numeric", s)
  for (i in 1:s)
  {
    L1 <- abs(d[, i ] - d)
    a[i] <- sum(L1)
  }
  return(a)
}


dd=as.data.frame(d)

DSS_p <- function(v) {
  return(sum(abs(v-d)))
}


library("purrr")   
library(microbenchmark)

microbenchmark(
  a1 <- DSS(d),
  a2 <- map_dbl(dd, DSS_p),
  times = 10L
)

单位:毫秒

                   expr      min       lq     mean   median       uq      max neval cld
            a1 <- DSS(d) 147.6936 151.5399 155.4522 154.9177 158.1982 167.6370    10  a 
a2 <- map_dbl(dd, DSS_p) 175.3692 181.0500 206.8654 184.5267 188.3336 320.7597    10   b