如何在 Python 中的 table 中进行二维插值?
How do make a 2D interpolation in a table in Python?
我有一个 table 数字,有两个初始行和列(粗体),它们是 CI 和 CII 的值作为输入。我的输入可以是这两个值之间的值,基于此我应该通过交叉 table 的值进行插值。
这么说吧,我应该从 table 中找到 CI = 0.33 的对应值,它在粗体第一行的 0.3 和 0.35 之间,CII = 1.1 .
关于 2D 插值的其他问题并没有真正帮助我解决这个问题。 因为 我正在使用 python 添加到另一个我无法导入的软件中 scipty.interp2D.
如果不需要特定库就可以提出一些解决方案,我将非常感激
我不确定要使用的插值类型。也许是线性的。为了提供更好的视角,我从 table 中绘制了 3 个任意行,仅取该行并根据样本编号绘制,看起来它们对样本有不同的行为。第一个增加,最后一个减少,但从来没有一条线:
你想要什么样的插值?多项式?指数分段平滑?逐步线性可以吗?
假设逐步线性,您可以手动编写一个函数:
# Sample data.
X = [0,5,10] # Left to right, like in your table.
Y = [0,2] # Top to bottom, like in your table.
grid = [[1,2,4],[4,5,10]]
def f(x,y):
# Find the vales that x and y are between.
xi,yi = None,None
for i,(x1,x2) in enumerate(zip(X[:-1],X[1:])):
if x1 <= x <= x2:
xi,w_x2,w_x1 = i,(x-x1)/(x2-x1),(x2-x)/(x2-x1)
break
for i,(y1,y2) in enumerate(zip(Y[:-1],Y[1:])):
if y1 <= y <= y2:
yi,w_y2,w_y1 = i,(y-y1)/(y2-y1),(y2-y)/(y2-y1)
break
if xi is None or yi is None:
return False
# You could add special cases to interpolate past the range if you would like.
# Find the weighted average between the four corners.
ave = grid[yi][xi] *w_y1*w_x1
ave += grid[yi][xi+1] *w_y1*w_x2
ave += grid[yi+1][xi] *w_y2*w_x1
ave += grid[yi+1][xi+1]*w_y2*w_x2
return ave
print(f(0,0),f(2.5,0),f(4,0),f(5,0),f(7.5,0),f(10,0))
print(f(0,1),f(2.5,1),f(4,1),f(5,1),f(7.5,1),f(10,1))
print(f(0,2),f(2.5,2),f(4,2),f(5,2),f(7.5,2),f(10,2))
如果有更多信息,这可以更有效地完成。例如,如果 x 值之间的 x_delta 一致,则可以跳过 for 循环。如果您使用 sortedcontainers 包中的 SortedList,您也可以跳过 for 循环。如果您想使用数组而不是列表等,这也可能适用于 numpy。
您没有提供任何工作代码或有关您可以使用的模块或您想要的算法的知识,所以我没有尽我所能就写了这篇文章。 :-)
编辑:
您不应该让人们从 PNG 图像中输入您的数据。这是一小部分,我无法输入更多。
X = [0,0.05,0.1,0.15,0.2]
Y = [0.2,0.4]
grid = [[1,1.116,1.211,1.297,1.376],[1,1.094,1.174,1.248,1.319]]
...
print(f(0,0.2),f(0.025,0.2),f(0.05,0.2))
我有一个 table 数字,有两个初始行和列(粗体),它们是 CI 和 CII 的值作为输入。我的输入可以是这两个值之间的值,基于此我应该通过交叉 table 的值进行插值。
这么说吧,我应该从 table 中找到 CI = 0.33 的对应值,它在粗体第一行的 0.3 和 0.35 之间,CII = 1.1 .
关于 2D 插值的其他问题并没有真正帮助我解决这个问题。 因为 我正在使用 python 添加到另一个我无法导入的软件中 scipty.interp2D. 如果不需要特定库就可以提出一些解决方案,我将非常感激
我不确定要使用的插值类型。也许是线性的。为了提供更好的视角,我从 table 中绘制了 3 个任意行,仅取该行并根据样本编号绘制,看起来它们对样本有不同的行为。第一个增加,最后一个减少,但从来没有一条线:
你想要什么样的插值?多项式?指数分段平滑?逐步线性可以吗?
假设逐步线性,您可以手动编写一个函数:
# Sample data.
X = [0,5,10] # Left to right, like in your table.
Y = [0,2] # Top to bottom, like in your table.
grid = [[1,2,4],[4,5,10]]
def f(x,y):
# Find the vales that x and y are between.
xi,yi = None,None
for i,(x1,x2) in enumerate(zip(X[:-1],X[1:])):
if x1 <= x <= x2:
xi,w_x2,w_x1 = i,(x-x1)/(x2-x1),(x2-x)/(x2-x1)
break
for i,(y1,y2) in enumerate(zip(Y[:-1],Y[1:])):
if y1 <= y <= y2:
yi,w_y2,w_y1 = i,(y-y1)/(y2-y1),(y2-y)/(y2-y1)
break
if xi is None or yi is None:
return False
# You could add special cases to interpolate past the range if you would like.
# Find the weighted average between the four corners.
ave = grid[yi][xi] *w_y1*w_x1
ave += grid[yi][xi+1] *w_y1*w_x2
ave += grid[yi+1][xi] *w_y2*w_x1
ave += grid[yi+1][xi+1]*w_y2*w_x2
return ave
print(f(0,0),f(2.5,0),f(4,0),f(5,0),f(7.5,0),f(10,0))
print(f(0,1),f(2.5,1),f(4,1),f(5,1),f(7.5,1),f(10,1))
print(f(0,2),f(2.5,2),f(4,2),f(5,2),f(7.5,2),f(10,2))
如果有更多信息,这可以更有效地完成。例如,如果 x 值之间的 x_delta 一致,则可以跳过 for 循环。如果您使用 sortedcontainers 包中的 SortedList,您也可以跳过 for 循环。如果您想使用数组而不是列表等,这也可能适用于 numpy。
您没有提供任何工作代码或有关您可以使用的模块或您想要的算法的知识,所以我没有尽我所能就写了这篇文章。 :-)
编辑:
您不应该让人们从 PNG 图像中输入您的数据。这是一小部分,我无法输入更多。
X = [0,0.05,0.1,0.15,0.2]
Y = [0.2,0.4]
grid = [[1,1.116,1.211,1.297,1.376],[1,1.094,1.174,1.248,1.319]]
...
print(f(0,0.2),f(0.025,0.2),f(0.05,0.2))