问题
需要确定一种方法来查找每个点具有值的2英里点集群 . 确定总和(值)> 50的2英里区域 .
数据
我的数据如下所示
ID COUNT LATITUDE LONGITUDE
187601546 20 025.56394 -080.03206
187601547 25 025.56394 -080.03206
187601548 4 025.56394 -080.03206
187601550 0 025.56298 -080.03285
大约200K记录 . 我需要确定的是,在一英里半径(2英里直径)区域内是否存在超过65的计数总和的区域 .
将每个点用作区域的中心
现在,我有另一个项目的python代码,它将在x直径点周围绘制一个shapefile,如下所示:
def poly_based_on_distance(center_lat,center_long, distance, bearing):
# bearing is in degrees
# distance in miles
# print ('center', center_lat, center_long)
destination = (vincenty(miles=distance).destination(Point(center_lat,
center_long), bearing).format_decimal())
以及返回目的地的例程,然后查看半径内的哪些点 .
## This is the evaluation for overlap between points and
## area polyshapes
area_list = []
store_geo_dict = {}
for stores in locationdict:
location = Polygon(locationdict[stores])
for areas in AREAdictionary:
area = Polygon(AREAdictionary[areass])
if store.intersects(area):
area_list.append(areas)
store_geo_dict[stores] = area_list
area_list = []
在这一点上,我只是在每个200K点周围绘制一个圆形shapefile,看看其他人在里面并进行计数 .
需要聚类算法?
但是,可能存在具有所需计数密度的区域,其中一个点不在中心 .
我熟悉使用属性进行分类的聚类算法,例如DBSCAN,但这是使用每个点的值找到密度聚类的问题 . 是否有任何聚类算法可以找到内径为> = 50的2英里直径圆的任何聚类?
任何建议,python或R都是首选工具,但这是开放式的,可能是一次性的,因此计算效率不是优先考虑的事情 .
2 回答
不是一个完整的解决方案,但它可能有助于简化问题,具体取决于您的数据分布 . 我将在我的示例中使用平面坐标和cKDTree,如果可以忽略投影中的曲率,这可能适用于地理数据 .
主要观察如下:如果
(x,y)
周围的半径为2*r
(例如2英里)的球的贡献小于截止值(例如 Headers 中的50),则(x,y)
点对密集星团没有贡献 . 实际上,(x,y)
的r
中的任何一点都不会对蚁群密集有贡献 .这允许您反复丢弃考虑点 . 如果你没有积分,就没有密集的星团;如果留下一些点,则可能存在聚类 .
虚拟数据示例:
可以调整DBSCAN(参见广义DBSCAN;将核心点定义为权重和> = 50),但它不能确保最大簇大小(它计算传递闭包) .
您也可以尝试完整的链接 . 用它来查找具有所需最大直径的簇,然后检查它们是否满足所需的密度 . 但这并不能保证找到所有 .
(a)为快速半径搜索构建索引可能更快 . (b)对于每一点,找到半径为r的邻居;如果他们有所需的最低金额,请保留 . 但这并不能保证找到所有内容,因为中心不一定是数据点 . 考虑最大半径为1,最小权重为100.两个点的权重为50,每个点为(0,0)和(1,1) . (0,0)处的查询和(1,1)处的查询都不会发现解,但(.5,.5)处的聚类满足条件 .
不幸的是,我相信你的问题至少是NP难的,所以你将无法负担最终的解决方案 .