计算一个数据框的每一行与另一个数据框中所有其他行之间的欧几里得距离。

8

我需要生成一个数据框,其中每行与另一个数据框的所有其他行之间的欧几里得距离最小。我的两个数据框都很大(约40,000行)。这是目前我能想到的方法。

x<-matrix(c(3,6,3,4,8),nrow=5,ncol=7,byrow = TRUE)     
y<-matrix(c(1,4,4,1,9),nrow=5,ncol=7,byrow = TRUE)


sed.dist<-numeric(5)
for (i in 1:(length(sed.dist))) {
sed.dist[i]<-(sqrt(sum((y[i,1:7] - x[i,1:7])^2)))
}

但这只适用于i=j的情况。我需要做的是循环遍历每一行(y [1,1:7],然后y [2,1:7]等,直到i = 5)"y"数据帧与所有行的" x "数据帧(x [i,1:7])查找最小欧几里得距离。每次执行此操作时,我需要它为y数据帧的第i行和x数据帧的所有行的每个计算找到最小的欧几里得距离,并将其存储在另一个数据帧中。


这个 sqrt(colSums((y[1, ] - t(x))^2)) 计算了 y 中第一行与 x 中所有行的距离。你想要对于 y 中的每一行都重复这个操作,并取得最小值吗? - alexis_laz
是的,那就是我想要的。 - user14845
2个回答

5

试试这个:

apply(y,1,function(y) min(apply(x,1,function(x,y)dist(rbind(x,y)),y)))
# [1] 5.196152 5.385165 4.898979 4.898979 5.385165

从内向外工作,我们将x的一行与y的一行绑定,并使用C编写的dist(...)函数计算它们之间的距离。我们使用内部apply(...)依次对给定的y行和每个x行进行此操作,然后找到结果的最小值。然后,我们在外部调用apply(...)时对每行y都执行此操作。


非常感谢,它完美地运行了,但是运行时间太长了。无论如何,还是谢谢你的帮助。 - user14845

3

针对我在问题中的评论,一个相当快速的方法是以下操作,尽管对于有40,000行数据的情况可能需要等待一些时间:

unlist(lapply(seq_len(nrow(y)), function(i) min(sqrt(colSums((y[i, ] - t(x))^2)))))
#[1] 5.196152 5.385165 4.898979 4.898979 5.385165

并进行比较基准测试:

x = matrix(runif(1e2*5), 1e2)
y = matrix(runif(1e2*5), 1e2)
library(microbenchmark)
alex = function() unlist(lapply(seq_len(nrow(y)), 
                           function(i) min(sqrt(colSums((y[i, ] - t(x))^2)))))
jlhoward = function() apply(y,1,function(y)
                                  min(apply(x,1,function(x,y)dist(rbind(x,y)),y)))
all.equal(alex(), jlhoward())
#[1] TRUE
microbenchmark(alex(), jlhoward(), times = 20)
#Unit: milliseconds
#       expr        min         lq     median         uq        max neval
#     alex()   3.369188   3.479011   3.600354   4.513114   4.789592    20
# jlhoward() 422.198621 431.565643 436.561057 442.643181 602.929742    20

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接