【问题标题】:How to get nearest neighbor of object point that have point_id using tree of Spatial.kdTree如何使用 Spatial.kdTree 的树获取具有 point_id 的对象点的最近邻居
【发布时间】:2026-01-13 19:10:02
【问题描述】:

帮帮我。我被困住了。我有一个classpoint。该类的属性是latLongpoint_idname。有些点具有相同的LatLong。所以,我需要point_id 作为积分标识。实际上,我想使用kdTree 的树来获得我点的最近邻居。我在构造kdTree 时没有问题,但是当我想知道我的点最近邻居时,结果是最近邻居的列表(Lat,Long) 而我想要point_id 作为我的结果,因为有些点具有相同的@987654334 @ 和 Long

这是我的代码:

import numpy as np
from scipy import spatial
import psycopg2
import math
import psycopg2.extensions   

class Point:
def __init__(self, id_point, name, Lat, Long):
    self.id_point=id_point
    self.name=name
    self.Lat=Lat
    self.Long=Long

def Struktur_KdTree(points):
    tree= spatial.KDTree(points)
    return tree

def getNearestPoint(tree,point,radius):
    return tree.query_ball_point(point,radius)

try:
   conn = psycopg2.connect("dbname='Chicago_crime' user='postgres' host='localhost' password='1234'")
except :
    print "I'm unable to connect to the database"

cur = conn.cursor()
cur.execute("""SELECT id_objek, primary_descript, lat, long from data_crime""")

data = []
Lat = []
Long = []
for id_jenis, jenis, lat, long in cur.fetchall():
     data.append(Point(id_point,name,Lat,Long))
     Lat.append(lat)
     Long.append(long)

dataPoints = zip (Lat,Long)

tree = Struktur_KdTree(dataPoints)
result=[]
radius=2
for point in dataPoint:
   result.append(getNearestPoint(tree,point,radius))

请给我一些建议?

【问题讨论】:

    标签: python python-2.7 kdtree spatial-index


    【解决方案1】:

    使用字典(或collections.defaultdict)记录从(lat, lng) 元组到Points 列表的映射。 有了这个字典(我们称之为pointmap),给定一个(lat, lng),你会 能够在该位置查找所有Points

    pointmap = collections.defaultdict(list)
    locations = set()
    for id_jenis, jenis, lat, lng in np.random.randint(10, size=(N, 4)):
        point = Point(id_jenis, jenis, lat, lng)
        pointmap[lat, lng].append(point)
    

    pointmap dict 中的键是 (lat, lng) 元组,我们可以将它们形成一个 NumPy 数组传递给spatial.KDTree

    locations = np.array(pointmap.keys())
    tree = spatial.KDTree(locations)
    

    现在,我们可以遍历每个位置并找到 最近的点:

    for loc in locations:
        indices = getNearestPoint(tree, loc, radius)
    

    请注意,query_ball_point 返回一个索引列表(该索引进入 locations)。实际位置由locations[indices] 给出。我们在这里 利用 NumPy 花式索引——因为locations 是 一个 NumPy 数组。

    对于location[indices] 中的每个位置,我们现在可以通过使用我们的字典pointmap 查找关联点来获得Points 的列表:

    near_points = [point for near_loc in locations[indices]
                   for point in pointmap[tuple(near_loc)]]
    

    把它们放在一起:

    import numpy as np
    from scipy import spatial
    import collections
    
    class Point:
    
        def __init__(self, id_point, name, Lat, Long):
            self.id_point = id_point
            self.name = name
            self.Lat = Lat
            self.Long = Long
    
        def __repr__(self):
            return 'Point({}, {}, {}, {})'.format(
                self.id_point, self.name, self.Lat, self.Long)
    
    def getNearestPoint(tree, point, radius):
        return tree.query_ball_point(point, radius)
    
    pointmap = collections.defaultdict(list)
    
    N = 10
    for id_jenis, jenis, lat, lng in np.random.randint(10, size=(N, 4)):
        point = Point(id_jenis, jenis, lat, lng)
        pointmap[lat, lng].append(point)
    
    locations = np.array(pointmap.keys())
    tree = spatial.KDTree(locations)
    
    result = []
    radius = 2
    
    for loc in locations:
        indices = getNearestPoint(tree, loc, radius)
        near_points = [point for near_loc in locations[indices]
                       for point in pointmap[tuple(near_loc)]]
        print('{} close to {}'.format(loc, near_points))
    

    产生如下输出:

    [8 3] close to [Point(2, 9, 8, 3)]
    [7 1] close to [Point(8, 6, 7, 1), Point(2, 1, 6, 1)]
    [4 5] close to [Point(7, 1, 4, 5), Point(4, 9, 3, 6)]
    [6 1] close to [Point(8, 6, 7, 1), Point(2, 1, 6, 1)]
    [2 0] close to [Point(0, 1, 2, 0), Point(4, 3, 4, 0)]
    [3 6] close to [Point(7, 1, 4, 5), Point(4, 9, 3, 6)]
    [7 9] close to [Point(1, 9, 7, 9)]
    [9 6] close to [Point(8, 5, 9, 6)]
    [2 4] close to [Point(4, 4, 2, 4)]
    [4 0] close to [Point(0, 1, 2, 0), Point(4, 3, 4, 0)]
    

    【讨论】:

    • 谢谢@unutbu。但我得到错误:Traceback (most recent call last): File "D:/s2/semester 3/tesis/phyton/Kdtree2.py", line 35, in <module> tree = spatial.KDTree(locations) File "C:\Python27\lib\site-packages\scipy\spatial\kdtree.py", line 229, in __init__ self.n, self.m = np.shape(self.data) ValueError: need more than 0 values to unpack
    • 我的错误。将集合转换为 NumPy 数组时,必须先将集合转换为元组或列表:locations = np.array(list(locations))
    • 感谢您的最佳解决方案和详细解释。你救了我???
    最近更新 更多