如何计算两个向量之间的欧几里得距离:
x1 <- rnorm(30)
x2 <- rnorm(30)
使用dist()
函数,但是你需要将前面的两个输入组成一个矩阵作为dist()
的第一个参数:
dist(rbind(x1, x2))
对于OP问题中的输入,我们得到:
> dist(rbind(x1, x2))
x1
x2 7.94821
一个单一的值,即x1
和x2
之间的欧几里得距离。
dist(rbind(x1,x2))
的速度快了三倍。 - JohnTortugo试着使用这个:
sqrt(sum((x1-x2)^2))
stats
包中使用norm
('F'代表Forbenius,即欧几里得范数):norm(matrix(x1-x2), 'F')
set.seed(1234)
x1 <- rnorm(300000000)
x2 <- rnorm(300000000)
> system.time(a<-sqrt(sum((x1-x2)^2)))
user system elapsed
1.02 0.12 1.18
> system.time(b<-norm(matrix(x1-x2), 'F'))
user system elapsed
0.97 0.33 1.31
tcrossprod
方法。bench=function(...,n=1,r=3){
a=match.call(expand.dots=F)$...
t=matrix(ncol=length(a),nrow=n)
for(i in 1:length(a))for(j in 1:n){t1=Sys.time();eval(a[[i]],parent.frame());t[j,i]=Sys.time()-t1}
o=t(apply(t,2,function(x)c(median(x),min(x),max(x),mean(x))))
round(100*`dimnames<-`(o,list(names(a),c("median","min","max","mean"))),r)
}
es=3:6
r=sapply(es,function(e){
m=matrix(rnorm(10^e),ncol=10)
v=rnorm(10)
bench(n=10,
tcrossprod={sqrt(outer(rowSums(m^2),rowSums(t(v)^2),"+")-tcrossprod(m,2*t(v)))},
Rfast_dista={Rfast::dista(m,t(v))},
vectorized={sapply(colSums((v-t(m))^2),sqrt)},
regular={apply(m,1,function(x)sqrt(sum((v-x)^2)))},
dotproduct={apply(m,1,function(x){q=v-x;sqrt(q%*%q)})},
norm={apply((v-t(m)),2,function(x)norm(as.matrix(x),"F"))},
rbind_single={apply(m,1,function(x)dist(rbind(v,x))[1])},
rbind_all={if(e<=5)unname(as.matrix(dist(rbind(v,m)))[1,-1])})[,1]
})
colnames(r)=paste0("1e",es)
r[8,4]=NA
round(r,3)
输出:
1e3 1e4 1e5 1e6
tcrossprod 0.004 0.012 0.093 0.972
Rfast_dista 0.003 0.013 0.115 1.148
vectorized 0.006 0.038 0.366 3.835
regular 0.021 0.181 1.901 20.437
dotproduct 0.020 0.183 2.010 24.560
norm 0.057 0.562 6.017 62.532
rbind_single 0.159 1.592 16.982 181.834
rbind_all 0.036 3.493 530.259 NA
dist()
中获取矩阵的,如果x1
和x2
只是OP中的两个向量。你使用了cbind()
吗? - Gavin Simpson