R(或Python)有没有加快地理空间分析的方法?

R(或Python)有没有加快地理空间分析的方法?,python,r,for-loop,optimization,geospatial,Python,R,For Loop,Optimization,Geospatial,我正在研究一个问题,在这个问题上,我正在确定彼此数据点之间距离内的数据点的性质。基本上,对于每一行数据,我试图确定地理范围内数据点的“邻域”,然后找出这个“邻域”的特征 问题是这是O^2问题,因为我目前嵌套了for循环,这意味着我正在运行nrow^2计算(我有70k行,所以有4.9B!计算……哎哟) 所以我的R(伪)代码是 for (i in 1:n.geopoints) { g1<-df[i,] for (j in 1:n.geopoints) { g2 <

我正在研究一个问题,在这个问题上,我正在确定彼此数据点之间距离内的数据点的性质。基本上,对于每一行数据,我试图确定地理范围内数据点的“邻域”,然后找出这个“邻域”的特征

问题是这是O^2问题,因为我目前嵌套了for循环,这意味着我正在运行nrow^2计算(我有70k行,所以有4.9B!计算……哎哟)

所以我的R(伪)代码是

for (i in 1:n.geopoints) {
   g1<-df[i,]
   for (j in 1:n.geopoints) {
      g2 <- df[j,]
      if (gdist(lat.1 = g1$lat, lon.1=g1$lon, lat.2 = g2$lat, lon.2 = g2$lon, units = "m") <= 1000) {
         [[[DO SOME STUFFF]]]
      }
   }
}
for(1:n地质点中的i){

g1这里有一种方法,它使用了
data.table
,以及我重新编写的haversine公式,以便在
data.table
操作中工作

这个想法是在每个点上对每个点进行
data.table
连接,但连接内计算每对点之间的距离,并删除阈值之外的点。这是受@Jaap的优秀

安装程序 哈弗森公式是

## Haversine formula
dt.haversine <- function(lat_from, lon_from, lat_to, lon_to, r = 6378137){
  radians <- pi/180
  lat_to <- lat_to * radians
  lat_from <- lat_from * radians
  lon_to <- lon_to * radians
  lon_from <- lon_from * radians
  dLat <- (lat_to - lat_from)
  dLon <- (lon_to - lon_from)
  a <- (sin(dLat/2)^2) + (cos(lat_from) * cos(lat_to)) * (sin(dLon/2)^2)
  return(2 * atan2(sqrt(a), sqrt(1 - a)) * r)
}
计算 现在我们有了数据和距离公式,我们可以构造
data.table
join

library(data.table)

## set the tram stop data as a data.table
dt1 <- as.data.table(tram_stops)

## add a column that will be used to do the join on
dt1[, joinKey := 1]

## find the dinstance between each point to every other point
## by joining the data to itself
dt2 <- dt1[
  dt1
  , {
    idx = dt.haversine(stop_lat, stop_lon, i.stop_lat, i.stop_lon) < 500 ## in metres
    .(stop_id = stop_id[idx],
      near_stop_id = i.stop_id)
  }
  , on = "joinKey"
  , by = .EACHI
]

笔记
<> >代码>数据>表<代码>连接应该是相当有效的,但是显然我在这里使用的数据只有51行;你必须让我知道这个方法如何适合你的数据

你可能想考虑一个不同的方法。我会使用一个像QGIS这样的GIS工具来分割你的数据。就像你说的,你不需要一个完整的笛卡尔连接。数据,只是局部聚类。看看一些聚类问题


GIS Stackexchange上的这个问题解决了800k数据点的类似问题。

您希望这个问题以多快的速度执行?您的目标是为每个点找到小半径(邻域)内的所有点吗?是的,没错。我不需要它是瞬间的,但我在本地钻机上运行它的时间是20小时。我很想在5小时内完成它。我知道嵌套for循环是一个很容易实现的结果,但我一直在努力通过一种方法来消除它。尝试查看数据结构,而不是列表。例如,点云L图书馆肯定会有适合你的问题的东西(而且执行速度非常快)。谢谢你-这为我指明了正确的方向。我使用了固定距离bugger,然后使用PostGIS中的空间查询来总结与每个缓冲线相交的所有点的特征。与笛卡尔关节的48小时以上相比,结果只有大约30分钟的处理能力。
library(data.table)

## set the tram stop data as a data.table
dt1 <- as.data.table(tram_stops)

## add a column that will be used to do the join on
dt1[, joinKey := 1]

## find the dinstance between each point to every other point
## by joining the data to itself
dt2 <- dt1[
  dt1
  , {
    idx = dt.haversine(stop_lat, stop_lon, i.stop_lat, i.stop_lon) < 500 ## in metres
    .(stop_id = stop_id[idx],
      near_stop_id = i.stop_id)
  }
  , on = "joinKey"
  , by = .EACHI
]
dt2 <- dt2[stop_id != near_stop_id]
mapKey <- "your_api_key"

## Just pick one to look at
myStop <- 18048
dt_stops <- dt3[stop_id == myStop ]

## get the lat/lons of each stop_id
dt_stops <- dt_stops[
  dt1      ## dt1 contains the lat/lons of all the stops
  , on = c(near_stop_id = "stop_id")
  , nomatch = 0
]

google_map(key = mapKey) %>%
  add_circles(data = dt1[stop_id == myStop], lat = "stop_lat", lon = "stop_lon", radius = 500) %>%
  add_markers(dt_stops, lat = "stop_lat", lon = "stop_lon")