【问题标题】:calculating the euclidean dist between each row of a dataframe with all other rows in another dataframe计算数据帧的每一行与另一个数据帧中的所有其他行之间的欧几里得距离
【发布时间】:2014-04-09 12:27:30
【问题描述】:

我需要生成一个数据帧的每一行与另一个数据帧的所有其他行之间具有最小欧几里德距离的数据帧。我的两个数据帧都很大(大约 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]依此类推,直到“y”数据帧的i = 5)与“x”数据帧的所有行(x [i,1:7])。每次执行此操作时,我都需要它来找到最小欧几里得距离对于 y 数据帧的第 i 行和 x 数据帧的所有行的每次计算,并将其存储在另一个数据帧中。

【问题讨论】:

  • 这个sqrt(colSums((y[1, ] - t(x))^2)) 计算y 中第1 行与x 中所有行的距离。你想要这个的min,并且,对于y中的每隔一行重复?
  • 是的,这就是我想要的

标签: r loops for-loop euclidean-distance


【解决方案1】:

扩展我对这个问题的评论,下面是一个非常快速的方法,虽然有 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

【讨论】:

    【解决方案2】:

    试试这个:

    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 并使用 dist(...) 函数(用 C 编写)计算它们之间的距离。我们对给定的 y 行和 x 的每一行依次执行此操作,使用内部 apply(...),然后找到结果的最小值。然后我们在对apply(...)的外部调用中对y的每一行执行此操作。

    【讨论】:

    • 非常感谢......它运行得非常好,但运行时间很长......不过感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2020-06-19
    • 2018-05-26
    • 2021-01-23
    • 2018-04-19
    • 2018-09-27
    • 2020-11-11
    • 2019-10-01
    相关资源
    最近更新 更多