我正在与纽约市出租车数据组合作。数据集有列,包括日期时间、拾取lat/lon、dropoff lat/lon等。现在,我想反向对lat/lon进行地理编码,以找到区/邻里。
我有两个数据帧。1)第一个数据帧包含了我想用最近的newyork邻域的名称分类的所有点。2)第二个数据帧包含邻域名称和它们的质心。
我给你举个小例子。
df_points_to_classify:点击这里下载原始csv
longitude latitude
<dbl> <dbl>
1 -73.99037 40.73470
2 -73.98078 40.72991
3 -73.98455 40.67957
4 -73.99347 40.71899 df_neighborhood_names_and_their_centroids:点击这里下载原始csv
longitude latitude neighborhood
<dbl> <dbl> <chr>
1 -73.8472005205491 40.89470517661004 Wakefield
2 -73.82993910812405 40.87429419303015 Co-op City
3 -73.82780644716419 40.88755567735082 Eastchester
4 -73.90564259591689 40.895437426903875 Fieldston 要将单点分配给邻域,我必须计算出从点到每个邻域质心的距离。很明显,这个点属于距离最短的邻域。
预期的输出包括在要分类的点的数据中添加一列,其中包含每个点所属的邻域。
预期产出:
longitude latitude neighborhood
<dbl> <dbl> <chr>
1 -73.99037 40.73470 Fieldston
2 -73.98078 40.72991 Co-op City
3 -73.98455 40.67957 etc...
4 -73.99347 40.71899 etc...我想使用一种计算效率高的方法,因为我要分类的点的数据库非常大(超过1GB)。由于这个原因,我在R上使用了spark。该文件已经以这种方式加载。
library(sparklyr)
sc <- spark_connect(master = "local")
df_points_to_classify <- spark_read_csv(sc, "D:\df_points_to_classify.csv")是否可以使用dplr来解决这个问题?
编辑:由于df_points_to_classify$any_variable的结果是NULL,所以这个解决方案在使用spark时不适用
library(spatialrisk)
ans <- purrr::map2_dfr(df_points_to_classify$longitude,
df_points_to_classify$latitude,
~spatialrisk::points_in_circle(df_neighborhood_names_and_their_centroids, .x, .y,
lon = longitude,
lat = latitude,
radius = 2000000)[1,])发布于 2019-10-24 13:17:47
我在下面添加了一个使用空间风险包的解决方案。这个包中的关键函数是用C++ (Rcpp)编写的,因此非常快。
首先,加载数据:
df1 <- data.frame(longitude = c(-73.99037, -73.98078, -73.98455, -73.99347),
latitude = c(40.73470, 40.72991, 40.67957, 40.71899))
df2 <- data.frame(longitude = c(-73.8472005205491, -73.82993910812405, -73.82780644716419, -73.90564259591689),
latitude = c(40.89470517661004, 40.87429419303015, 40.88755567735082, 40.895437426903875),
neighborhood = c("Wakefield", "Co-op City", "Eastchester", "Fieldston"))函数spatialrisk::points_in_circle()从中心点计算半径内的观测值。请注意,距离是使用Haversine公式计算的。由于输出的每个元素都是数据框架,所以使用purrr::map_dfr将它们绑定在一起:
ans <- purrr::map2_dfr(df1$longitude,
df1$latitude,
~spatialrisk::points_in_circle(df2, .x, .y,
lon = longitude,
lat = latitude,
radius = 2000000)[1,])
cbind(df1, ans)
longitude latitude longitude latitude neighborhood distance_m
1 -73.99037 40.73470 -73.90564 40.89544 Fieldston 19264.50
2 -73.98078 40.72991 -73.90564 40.89544 Fieldston 19483.54
3 -73.98455 40.67957 -73.90564 40.89544 Fieldston 24933.59
4 -73.99347 40.71899 -73.90564 40.89544 Fieldston 20989.84发布于 2019-10-26 02:13:48
这里有一个完整的解决方案,不是最有效率的,而是基于我的机器估计的。表约90分钟为1200万开始的地点。
是的,这可以使效率更高,但如果这是一次运行,设置它,忘记,然后回来为结果。要提高效率,一个可能的选择是将位置圈到小数点3或4位,并且只查找唯一位置的位置,然后将结果返回到原始数据。
library(readr)
library(dplyr)
library(stringr)
#read tax data in
taxi<-read_csv("yellow.csv")
#Removed unneeded columns (reduces memory requirements and improves speed)
taxi <- taxi %>% select( c(2:7, 10, 11, 13, 16 ))
#filter out rows that have bad data (far outside expected area)
taxi <- taxi %>% filter(pickup_longitude > -75 & pickup_longitude < -70)
taxi <- taxi %>% filter(dropoff_longitude > -75 & dropoff_longitude < -70)
taxi <- taxi %>% filter(pickup_latitude > 35 & pickup_latitude < 45)
taxi <- taxi %>% filter(dropoff_latitude > 35 & dropoff_latitude < 45)
point_class<-taxi[1:200000,] #reduce the sized of the starting vector for testing
#read neighborhood data and clean up data
df_neighborhood<-read.csv("NHoodNameCentroids.csv", stringsAsFactors = FALSE)
location<-str_extract(df_neighborhood$the_geom, "[-0-9.]+ [-0-9.]+")
location<-matrix(as.numeric(unlist(strsplit(location, " "))), ncol=2, byrow=TRUE)
df_neighborhood$longitude<- location[,1]
df_neighborhood$latitude <- location[,2]
df_neighborhood<-df_neighborhood[, c("OBJECTID", "Name", "Borough", "longitude", "latitude")]
#find closest neighbor to starting location
library(geosphere)
start<-Sys.time()
#preallocate the memory to store the result
neighborhood<-vector(length=nrow(point_class))
for (i in 1:nrow(point_class)) {
distance=distGeo(point_class[i,5:6], df_neighborhood[,4:5])
neighborhood[i]<-which.min(distance)
}
point_class$neighorhood<-df_neighborhood$Name[neighborhood]
point_class
print(Sys.time()-start)https://stackoverflow.com/questions/58540031
复制相似问题