我想知道在Python中为浮点数(以及浮点数集合)创建查找表的最有效方法是什么。由于两个组和dicts都需要键可以清洗,我猜不能使用某种接近来检查已经插入的接近度,是吗?我看过this answer并不是我想要的,因为我不想给用户创造正确密钥的负担,而且我需要扩展它用于花车的集合。 例如,给出以下代码:
>>> import numpy as np
>>> a = {np.array([0.01, 0.005]): 1}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'numpy.ndarray'
>>> a = {tuple(np.array([0.01, 0.005])): 1}
>>> tuple(np.array([0.0100000000000001,0.0050002])) in a
False
我希望最后一句话返回True
。来自C ++世界,我将创建一个std::map
并提供一个比较函数,该函数可以与某些用户定义的容差进行比较,以检查这些值是否已添加到数据结构中。当然,这个问题自然会扩展到数组的查找表(例如numpy数组)。那么,什么是实现我所寻找的最有效的方式?
答案 0 :(得分:1)
由于您对3D点感兴趣,因此您可以考虑使用一些针对存储空间数据进行优化的数据结构,例如KD-tree。这是Scipy中的available,允许查找最接近给定坐标的点。在您查看了这一点之后,您可以检查一下您是否在接受新点的容忍范围内。
用法应该是这样的(未经测试,我自己从未使用过):
from scipy.spatial import KDTree
points = ... # points is [Nx3]
tree = KDTree(points)
new_point = ... # array of length 3
distance, nearest_index = tree.query(new_point)
if distance > tolerance: # add point
points = np.vstack((points, new_point))
tree = KDTree(points) # generate tree from scratch
请注意,KD树在查找静态点集合中的点是有效的(查找成本为O(log(N))
,但它们未针对重复添加新点进行优化.Scipy实现甚至缺乏添加新点的方法,因此每次插入新点时都必须生成一个新树。由于此操作可能是O(N*log(N))
,因此对所有距离进行强力计算可能更快,费用为O(N)
。请注意,还有一个替代版本cKDTree,可能在C中实现了速度,文档在这方面并不是很清楚。