R语言中的快速距离计算

R语言中的快速距离计算,r,matrix,numerical-methods,euclidean-distance,mahalanobis,R,Matrix,Numerical Methods,Euclidean Distance,Mahalanobis,我在试着计算 1) 欧几里德距离,以及 2) 马氏距离 对于r。我一直在这样做: v1 <- structure(c(0.508, 0.454, 0, 2.156, 0.468, 0.488, 0.682, 1, 1.832, 0.44, 0.928, 0.358, 1, 1.624, 0.484, 0.516, 0.378, 1, 1.512, 0.514, 0.492, 0.344, 0, 1.424, 0.508, 0.56, 0.

我在试着计算

1) 欧几里德距离,以及

2) 马氏距离

对于r。我一直在这样做:

v1 <- structure(c(0.508, 0.454, 0, 2.156, 0.468, 0.488, 0.682, 1, 1.832, 
            0.44, 0.928, 0.358, 1, 1.624, 0.484, 0.516, 0.378, 1, 1.512, 
            0.514, 0.492, 0.344, 0, 1.424, 0.508, 0.56, 0.36, 1, 1.384, 0.776, 
            1.888, 0.388, 0, 1.464, 0.952, 0.252, 0.498, 1, 1.484, 0.594, 
            0.256, 0.54, 2, 2.144, 0.402, 0.656, 2.202, 1, 1.696, 0.252), 
          .Dim = c(5L, 10L), 
          .Dimnames = list(NULL, c("KW_1", "KW_2", "KW_3", "KW_4", "KW_5", "KW_6", "KW_7", "KW_8", "KW_9", "KW_10")))

v2 <- structure(c(1.864, 1.864, 1.864, 1.864, 1.864, 1.6, 1.6, 1.6, 
            1.6, 1.6, 1.536, 1.536, 1.536, 1.536, 1.536, 1.384, 1.384, 1.384, 
            1.384, 1.384, 6.368, 6.368, 6.368, 6.368, 6.368, 2.792, 2.792, 
            2.792, 2.792, 2.792, 2.352, 2.352, 2.352, 2.352, 2.352, 2.624, 
            2.624, 2.624, 2.624, 2.624, 1.256, 1.256, 1.256, 1.256, 1.256, 
            1.224, 1.224, 1.224, 1.224, 1.224), 
          .Dim = c(5L, 10L), 
          .Dimnames = list(NULL, c("KW_1", "KW_2", "KW_3", "KW_4", "KW_5", "KW_6", "KW_7", "KW_8", "KW_9", "KW_10")))

L2 <- sqrt(rowSums((v1-v2)^2))  # Euclidean distance for each row
太好了!但我听说你也可以用以下形式计算欧几里德/L2距离:

我想用这种方法计算我的距离,因为马氏距离就是这个,协方差矩阵

然而,我还没有弄明白如何在r中编写这个代码。我试过:

sqrt(crossprod((t(v1)-t(v2))))

但他们就是不给我想要的。建议

注-
我希望把它作为一个单独的操作来完成,而不是任何形式的循环。它必须非常快,因为我要在数百万行上重复多次。也许这是不可能的。我愿意更改
v1
v2

的格式。您需要将公式分别应用于每一行,例如:

> sapply(1:nrow(v1), function(i) {
+     q = v1[i, ] - v2[i, ]
+     d = sqrt(t(q) %*% q)
+     d
+ })
[1] 7.132452 7.568359 7.536904 5.448696 7.163580

如果你需要更快的东西,你可以在C++中尝试同样的事情(代码改编自:


不,我需要每行的距离。结果必须匹配
[1]7.132452 7.568359 7.536904 5.448696 7.163580
我的数据集中有数百万行,因此速度不够快。如果您有限制和要求,在您的问题中告诉我们可能是一个好主意。Dan,查找data.table包。这将有助于您处理如此大的数据集。在这个站点上,你会发现很多关于使用这个包的信息。@丹:你可以在C++中基本上应用相同的代码来加速。非常酷的是<代码> Rcpp <代码>动作。我已经实现了用L1加速,而不幸的是,在C++中,<代码> SqRT(ROWSUM((V1-V2)^ 2))< /> >比<>代码> < /Cult>循环更快。这就有两点:1)有没有一种方法可以将代码> > Sqt(ROWSUM((V1-V2)^ 2))< /COD>转换成C++?以避免
for
循环?2)如何使用
C++
实现
Mahalanobis
距离?我将在上面的
C++
中发布我的最佳照片。
sqrt((v1-v2) %*% t(v1-v2))
> sapply(1:nrow(v1), function(i) {
+     q = v1[i, ] - v2[i, ]
+     d = sqrt(t(q) %*% q)
+     d
+ })
[1] 7.132452 7.568359 7.536904 5.448696 7.163580
#include <Rcpp.h>

using namespace Rcpp;

double dist2(NumericVector x, NumericVector y){
    double d = sqrt( sum( pow(x - y, 2) ) );
    return d;
}

// [[Rcpp::export]]
NumericVector calc_l2 (NumericMatrix x, NumericMatrix y){
    int out_length = x.nrow();
    NumericVector out(out_length);

    for (int i = 0 ; i < out_length; i++){
        NumericVector v1 = x.row(i);
        NumericVector v2 = y.row(i);
        double d = dist2(v1, v2);
        out(i) = d;
    }
    return (out) ;
}
library(Rcpp)

sourceCpp("calc_L2.cpp")
calc_l2(v1, v2)