使用Numpy实现KD树时出现切片索引类型错误的技术问询
Fixing "slice indices must be integers or None or have an index method" in KD Tree Implementation with NumPy
看起来你在构建KD树时遇到了切片索引的类型错误,这个问题的核心是你用来分割数组的median变量不是整数类型——NumPy的数组切片要求起始/结束索引必须是整数(或None),如果median是浮点数,就会抛出这个错误。
问题根源
通常这个问题出在KD树构建的逻辑混淆上:很多人会把「中位数的数值」和「中位数所在的位置索引」搞混。比如如果你直接用np.median()计算当前维度的中位数数值,得到的结果会是浮点数(哪怕数组长度是奇数,返回的也是float类型),用这个数值去做数组切片自然会触发类型错误。
解决方案
你需要调整代码逻辑,找到排序后点集的中间位置的整数索引,而非中位数的数值。具体修改步骤如下:
- 先确定当前递归层级的分割维度
- 按该维度对所有点进行排序
- 用整数索引分割出左右子树的点集
- 递归构建子树
修改后的完整代码片段:
class node: def __init__(self): self.point = None self.left = None self.right = None def makeKDtree(points, depth): if len(points) == 0: return None # 确定当前分割维度(循环切换x、y...轴) dim = depth % points.shape[1] # 按当前维度的坐标排序,获取排序后的索引 sorted_indices = np.argsort(points[:, dim]) sorted_points = points[sorted_indices] # 计算中间位置的整数索引(地板除法保证结果为整数) median_idx = len(sorted_points) // 2 # 分割左右子树的点集(用整数索引切片) goLeft = sorted_points[:median_idx, :] goRight = sorted_points[median_idx+1:, :] # 创建节点并递归构建子树 newNode = node() newNode.point = sorted_points[median_idx, :] newNode.left = makeKDtree(goLeft, depth+1) newNode.right = makeKDtree(goRight, depth+1) return newNode # 假设你已经实现了returnNearest函数 def returnNearest(tree, target, depth): # 你的最近邻搜索逻辑 pass # 测试代码 points = np.array([[1,6],[2,2],[3,7],[5,4],[6,8],[6,1],[7,5]]) tree = makeKDtree(points,0) print(returnNearest(tree, np.array([3,5]), 0)) print(returnNearest(tree, np.array([4.5,2]), 0))
关键说明
- 使用
len(sorted_points) // 2而非浮点数索引:地板除法会返回整数结果,不管点集长度是奇数还是偶数,完全符合NumPy数组切片的类型要求。 - 先排序再分割:KD树的核心逻辑是在每个维度上选择中间点作为分割点,这样能保证树的平衡性,避免出现倾斜树导致搜索效率下降。
内容的提问来源于stack exchange,提问作者Thien Hua
相关产品推荐
相关产品推荐

