我有一个长数字表,其中7列是键,4列是要查找的值。
实际上我已经渲染了一个具有不同距离和透视角度的物体,并计算了它的轮廓的Hu矩。但这对问题来说并不重要,只是一个想象的样本。
所以,当我有7个值时,我需要扫描一个表,找到该7列中最接近的值并提取相应的4个值。
因此,需要考虑的任务方面如下:
1)数字有错误
2)功能域中的比例与功能值中的比例不同;即,与7维空间中的点的“距离”应该取决于4个值,它如何影响
3)搜索应该快速
所以问题如下:是不是有一些算法可以有效地解决这个问题,即在7列上执行一些索引,但这样做不像传统数据库那样,但考虑到上面的点。
答案 0 :(得分:2)
如果我正确理解了问题,您可以考虑使用scipy.cluster.vq(矢量量化):
假设您的7个数字列看起来像这样(让我们调用数组code_book
):
import scipy.cluster.vq as vq
import scipy.spatial as spatial
import numpy as np
np.random.seed(2013)
np.set_printoptions(precision=2)
code_book = np.random.random((3,7))
print(code_book)
# [[ 0.68 0.96 0.27 0.6 0.63 0.24 0.7 ]
# [ 0.84 0.6 0.59 0.87 0.7 0.08 0.33]
# [ 0.08 0.17 0.67 0.43 0.52 0.79 0.11]]
假设关联的4列值如下所示:
values = np.arange(12).reshape(3,4)
print(values)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
最后,假设我们对7列值有一些“观察”,如下所示:
observations = np.random.random((5,7))
print(observations)
# [[ 0.49 0.39 0.41 0.49 0.9 0.89 0.1 ]
# [ 0.27 0.96 0.16 0.17 0.72 0.43 0.64]
# [ 0.93 0.54 0.99 0.62 0.63 0.81 0.36]
# [ 0.17 0.45 0.84 0.02 0.95 0.51 0.26]
# [ 0.51 0.8 0.2 0.9 0.41 0.34 0.36]]
要找到最接近每个观察的code_book
中的7值行,您可以使用vq.vq:
index, dist = vq.vq(observations, code_book)
print(index)
# [2 0 1 2 0]
索引值是指code_book
中的行。但是,如果values
中的行的排序方式与code_book
相同,我们可以使用values[index]
“查找”相关值:
print(values[index])
# [[ 8 9 10 11]
# [ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]
# [ 0 1 2 3]]
以上假设您将所有观察结果排列在一个数组中。因此,要查找所有索引,您只需要拨打vq.vq
一次。
但是,如果您一次获得一个观察结果,并且需要在进行下一次观察之前找到code_book
中最近的行,那么每次调用vq.vq
都是低效的。相反,生成一次KDTree ,然后在树中找到最近的邻居:
tree = spatial.KDTree(code_book)
for observation in observations:
distances, indices = tree.query(observation)
print(indices)
# 2
# 0
# 1
# 2
# 0
请注意,与简单穷举搜索相比,KDTree的code_book
(N
)must be large compared to the dimension数据(例如N >> 2**7
)的点数要快
使用vq.vq
或KDTree.query
可能会或不会比穷举搜索更快,具体取决于您的数据大小(code_book
和observations
)。要找出哪个更快,请务必使用timeit对这些进行基准测试与穷举搜索。
答案 1 :(得分:1)
我不知道我是否理解你的问题,但我会尝试给出答案。
表中每行K计算键与该行中键的距离:
((X1-K1)^ 2 +(X2-K2)^ 2 +(X3-K3)^ 2 +(X4-K4)^ 2 +(X5-K5)^ 2 +(X6- K6)^ 2 +(X7-K7)^ 2)^ 0.5
其中{X1,X2,X3,X4,X5,X6,X7}是键,{K1,K2,K3,K4,K5,K6,K7}是K行的关键
你可以使一个关键因素或多或少与其他关键因素相乘,同时计算距离,例如你可以用(X1-K1)^ 2 > 5 *(X1-K1)^ 2 使其更加流入。
并在变量中存储距离,在第二个变量中存储行号
对以下行执行相同操作,如果新距离低于您存储的距离,则替换距离和行号。
当您检查了表格中的所有行时,您使用的第二个变量将显示距离键最近的行
这里有一些伪代码:
int Row= 0
float Key[7] #suppose it is already filled with some values
float ClosestDistance= +infinity
int ClosestRow= 0
while Row<NumberOfRows{
NewDistance= Distance(Key,Table[Row][0:7])#suppose Distance is a function that outputs the distance and Table is the table you want to control Table[Row= NumberOfRows][Column= 7+4]
if NewDistance<ClosestDistance{
ClosestDistance= NewDistance
ClosestRow= Row}
increase row by 1}
ValueFound= Table[ClosestRow][7:11]#this should be the value you were looking for
我知道它并不快,但它是我能做的最好的,希望它有所帮助。
P.S。我知道,我没有考虑测量误差。