如何计算欧几里得距离(并只保存摘要)大型数据帧(How to calculate Euclidean

2019-09-02 10:59发布

我写了一个简短的for循环找到最小欧式每行之间的数据帧和所有其他行距离(并记录该行最近的)。 在理论上,这避免了与试图计算距离的措施非常大的矩阵相关的误差。 然而,虽然没有那么多被保存在内存中,这是非常大型矩阵(〜150K行的我用例仍在运行)非常缓慢。

我不知道是否有人可以建议或向量化我的功能,使用应用或类似的术语点我在正确的方向。 什么道歉似乎是一个简单的问题,但我仍然在努力想在向量化的方式。

在此先感谢(和你的耐心)。

require(proxy)

df<-data.frame(matrix(runif(10*10),nrow=10,ncol=10), row.names=paste("site",seq(1:10)))

min.dist<-function(df) {  
 #df for results
 all.min.dist<-data.frame()
 #set up for loop 
 for(k in 1:nrow(df)) {
     #calcuate dissimilarity between each row and all other rows
     df.dist<-dist(df[k,],df[-k,])
     # find minimum distance
     min.dist<-min(df.dist)
     # get rowname for minimum distance (id of nearest point)
     closest.row<-row.names(df)[-k][which.min(df.dist)]
     #combine outputs
     all.min.dist<-rbind(all.min.dist,data.frame(orig_row=row.names(df)[k],
     dist=min.dist, closest_row=closest.row))
    }
 #return results
 return(all.min.dist)
                        } 
 #example
 min.dist(df)

Answer 1:

这应该是一个良好的开端。 它采用快速矩阵运算,避免了不断增长的对象结构,在双方意见建议。

min.dist <- function(df) {

  which.closest <- function(k, df) {
    d <- colSums((df[, -k] - df[, k]) ^ 2)
    m <- which.min(d)
    data.frame(orig_row    = row.names(df)[k],
               dist        = sqrt(d[m]),
               closest_row = row.names(df)[-k][m])
  }

  do.call(rbind, lapply(1:nrow(df), which.closest, t(as.matrix(df))))
}

如果这仍然太慢,作为建议的改进,你可以在一个时间,而不是单一的一个计算的k个点的距离。 k的大小将需要速度和内存使用之间的一种折衷。

编辑:还可以阅读https://stackoverflow.com/a/16670220/1201032



Answer 2:

通常,内置函数是快于自己编码它(因为用Fortran或C / C ++编码和优化)。

如此看来,功能DIST {}统计回答您的问题点上:

描述此函数计算,并返回通过使用指定的距离度量以计算数据矩阵的行之间的距离计算的距离矩阵。



文章来源: How to calculate Euclidean distance (and save only summaries) for large data frames