从查找表中插值数据

14

阅读查找表

LUT = np.genfromtxt('test.out', delimiter=',', dtype=float)
LUT:
    12, 25, 136, 6743
    13, 26, 139, 6786
    14, 27, 142, 6791
    15, 28, 145, 6789

需要从LUT中读取的数值如下:

x1, x2, x3 = 12.5, 25.5, 137

对于每个给定的值(3列),读取LUT中相邻两个值,并进行线性插值以得到结果(LUT中的第4列)。

给定值(x1、x2、x3)属于LUT的第1行和第2行之间。根据此,如何在第1行和第2行之间读取结果?


1
这里不太清楚您想要什么。您有一个三维坐标空间。您需要进行三维线性插值吗?看起来您没有足够的数据,因为您的数据沿着 x3 = 3*x1+100, x2=x1+13 这条线,而您所需的坐标不在该线上(12.5,25.5,137.5 在该线上)。如果您只对该线上的事物感兴趣,则一维插值可行;如果您对其外的事物感兴趣,则需要获取该线外的数据。 - cge
@cge 不,我必须找出LUT中x1、x2和x3存在的下限和上限索引。它在第一行和第二行之间。但是如何通过程序知道呢?如果已知结果,则可以通过线性插值获得6743和6786的结果。 - Borys
1
如果你有x1、x2、x3=12.5、26.3、144,会发生什么?或者它们总是在同两行之间吗?如果是这样,前三列是否总是严格递增的?通过线性插值,你是指平均值吗?因为如果你实际上想要基于x1、x2、x3值进行线性插值,那么如何做并不明显。 - cge
@talonmies 对不起,三列严格递增,但预期结果始终在相同的两行之间。 - Borys
很不幸,我必须同意@MarkRansom的观点。在我看来,你只需要赋值c1 = LUT[:, 0],(c2=, c3= ...)然后x1 = (c1[0] + c1[1]) / 2 (x2=, x3=),这已经基本上完成了。 - Matthew
显示剩余3条评论
2个回答

9

给定一个要进行插值的坐标列表coords,您可以使用 scipy.spatial.cKDTree来获取您的表中线性插值所必需的2个最接近的条目。下面的代码显示了一个已经向量化的用法示例。

import numpy as np
from scipy.spatial import cKDTree

# inputs
LTU = np.genfromtxt('test.txt', delimiter=',')

coords = ((12.5, 25.5, 137),
          (13.5, 26.5, 141),
          (14.5, 25.5, 144))

# querying and interpolating
xyz = LTU[:, :3]
val = LTU[:, 3]

del LTU # attempt to clean up memory

tree = cKDTree(xyz)
dist, ind = tree.query(coords, k=2)

d1, d2 = dist.T
v1, v2 = val[ind].T
v = (d1)/(d1 + d2)*(v2 - v1) + v1

print(v)
#[ 6758.73909236  6789.16987298  6790.03575996]

我的LUT大约有1GB。你的代码能处理大数据吗?或者有其他方法可以保留LUT而不是以文本文件形式进行更快的读取? - Borys
@Borys 1GB不应该是问题...我已经添加了一个del LTU命令,试图清理内存。 - Saullo G. P. Castro
非常好的答案,对我很有用,但我不理解插值的那一行代码:v = (d1)/(d1 + d2)*(v2 - v1) + v1。 - dorbodwolf

2
有点不清楚——你正在处理什么样的上下文。
如果这是一个更一般性的LUT:通过欧几里得距离找到最接近所提供点的所有LUT中的两个点。在确定了这两个点之后,在第四列上使用双线性插值
如果每列都与(1,1,3)以同步方式增加,并且您对此有一些排序概念,则使用Python的bisect模块查找第一列的上限和下限,然后就可以找到您将用于插值的索引(双线性?)。由于您在下面的评论中提到delta是固定的,因此这使得这更像是一个一维LUT问题而不是三维问题 - 可以仅使用第一维和第四维使用numpy.interp
如果它们不是完全一致的,但仍保留类似的排序方式,那么可以通过在列之间生成累积上/下限来限制允许的上/下标范围,然后决定您想要在该范围内进行插值的索引。
对于所有这些情况,如果在LUT中找到了精确的值,则不需要进行插值。

1
每一列都会同步增加。您能提供实现此目的的可行代码吗? - Borys

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接