我有以下三个列表:
x = [100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0]
y = [300.0, 300.0, 300.0, 300.0, 500.0, 500.0, 500.0, 500.0, 700.0, 700.0, 700.0, 700.0, 1000.0, 1000.0, 1000.0, 1000.0, 1500.0, 1500.0, 1500.0, 1500.0, 2000.0, 2000.0, 2000.0, 2000.0, 3000.0, 3000.0, 3000.0, 3000.0, 5000.0, 5000.0, 5000.0, 5000.0, 7500.0, 7500.0, 7500.0, 75000.0, 10000.0, 10000.0, 10000.0, 10000.0]
z = [100.0, 95.0, 87.5, 77.5, 60.0, 57.0, 52.5, 46.5, 40.0, 38.0, 35.0, 31.0, 30.0, 28.5, 26.25, 23.25, 23.0, 21.85, 20.125, 17.825, 17.0, 16.15, 14.875, 13.175, 13.0, 12.35, 11.375, 10.075, 10.0, 9.5, 8.75, 7.75, 7.0, 6.65, 6.125, 5.425, 5.0, 4.75, 4.375, 3.875]
每个列表的每个条目都被读为一个点,因此点0是(100,300,100)点1是(75,300,95),依此类推。
我正在尝试进行2d插值,以便可以为任何给定的输入(x0, y0)
点计算z值。
我读到,使用meshgrid可以从scipy插值RegularGridInterpolator
,但是我不确定如何设置它:
x_,y_,z_ = np.meshgrid(x,y,z) # both indexing ij or xy
我没有得到x_,y_,z_
有意义的值,而且我不确定该怎么去。
我正在尝试使用上面的数据点来查找中间值,因此类似于scipy的interp1d
其中
f = interp1d(x, y, kind='cubic')
稍后我可以在其中调用f(any (x,y) point within range)
并获取相应的z
值。
答案 0 :(得分:1)
您需要对分散的数据进行二维插值。在这种情况下,我默认使用scipy.interpolate.griddata
,但是您似乎想要一个 callable 插值器,而griddata
需要一个要插入点的给定点集。 / p>
不用担心:具有二维三次插值的griddata
使用CloughTocher2DInterpolator
。所以我们可以做到这一点:
import numpy as np
import scipy.interpolate as interp
x = [100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0, 100.0, 75.0, 50.0, 0.0]
y = [300.0, 300.0, 300.0, 300.0, 500.0, 500.0, 500.0, 500.0, 700.0, 700.0, 700.0, 700.0, 1000.0, 1000.0, 1000.0, 1000.0, 1500.0, 1500.0, 1500.0, 1500.0, 2000.0, 2000.0, 2000.0, 2000.0, 3000.0, 3000.0, 3000.0, 3000.0, 5000.0, 5000.0, 5000.0, 5000.0, 7500.0, 7500.0, 7500.0, 75000.0, 10000.0, 10000.0, 10000.0, 10000.0]
z = [100.0, 95.0, 87.5, 77.5, 60.0, 57.0, 52.5, 46.5, 40.0, 38.0, 35.0, 31.0, 30.0, 28.5, 26.25, 23.25, 23.0, 21.85, 20.125, 17.825, 17.0, 16.15, 14.875, 13.175, 13.0, 12.35, 11.375, 10.075, 10.0, 9.5, 8.75, 7.75, 7.0, 6.65, 6.125, 5.425, 5.0, 4.75, 4.375, 3.875]
interpolator = interp.CloughTocher2DInterpolator(np.array([x,y]).T, z)
现在,您可以使用2个坐标调用此插值器,以为您提供相应的插值数据点:
>>> interpolator(x[10], y[10]) == z[10]
True
>>> interpolator(2, 300)
array(77.81343)
请注意,您必须留在输入点的凸包内,否则将得到nan
(或作为fill_value
关键字传递给插值器的任何内容):>
>>> interpolator(2, 30)
array(nan)
外推通常是毫无意义的,而且您的输入点以某种不稳定的方式散布:
所以即使可以推断,我也不相信。
仅是为了演示如何将所得的插值器约束到输入点的凸包,这是我们为绘制而创建的网格网格上的数据表面图:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# go linearly in the x grid
xline = np.linspace(min(x), max(x), 30)
# go logarithmically in the y grid (considering y distribution)
yline = np.logspace(np.log10(min(y)), np.log10(max(y)), 30)
# construct 2d grid from these
xgrid,ygrid = np.meshgrid(xline, yline)
# interpolate z data; same shape as xgrid and ygrid
z_interp = interpolator(xgrid, ygrid)
# create 3d Axes and plot surface and base points
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(xgrid, ygrid, z_interp, cmap='viridis',
vmin=min(z), vmax=max(z))
ax.plot(x, y, z, 'ro')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.show()
这是两个角度的输出(最好以交互方式旋转;这样的静止图像不能使3d表示法更加公正)
要注意两个主要功能:
nan
值),因此,即使我们的网格阵列定义了矩形网格,我们也只能在有意义的插补位置上切割曲面。 / li>