我正在努力将大小为
Nx*Ny*Nz
的数据立方体执行简单的线性插值到一个新的数据立方体中,以保持其他两个维度不变,即结果输出将是Nxnew*Ny*Nz
。看来 RegularGridInterpolator
中的 scipy
似乎是可行的方法,尽管对我来说如何生成输入并不直观。
from scipy.interpolate import RegularGridInterpolator
import numpy as np
x = np.linspace(1,4,11)
y = np.linspace(4,7,22)
z = np.linspace(7,9,33)
V = np.zeros((11,22,33))
for i in range(11):
for j in range(22):
for k in range(33):
V[i,j,k] = 100*x[i] + 10*y[j] + z[k]
fn = RegularGridInterpolator((x,y,z), V)
pts = np.array([[[[2,6,8],[3,5,7]], [[2,6,8],[3,5,7]]]])
out = fn(pts)
print(out, out.shape)
在此 mwe 中,我想使用新点
xnew = np.linspace(2,3,50)
,同时保持 y
和 z
相同,因此生成的数组变为形状 (50,22,33)
。另外,如何将其推广为 n 维数组沿 1 维的插值,同时保持其余坐标相同?
按照评论中的建议,您可以替换三重嵌套循环,以使代码更具可读性和更高效。
x, y, z = np.meshgrid(x, y, z, indexing='ij')
V = 100*x + 10*y + z
至于生成
fn
对象的输入:
它需要三个一维坐标数组。您实际上想在 len(xnew) * len(y) * len(z)
不同的点评估函数。我们可以使用 meshgrid
生成 3D 数组中的所有这些点,然后 ravel
数组使它们成为 1d
。在这些输入上调用 fn
后,我们根据需要重塑 out
。
from scipy.interpolate import RegularGridInterpolator
import numpy as np
x0 = np.linspace(1, 4, 11)
y0 = np.linspace(4, 7, 22)
z0 = np.linspace(7, 9, 33)
x, y, z = np.meshgrid(x0, y0, z0, indexing='ij')
V = 100*x + 10*y + z
fn = RegularGridInterpolator((x0, y0, z0), V)
xnew = np.linspace(2, 3, 50)
x, y, z = np.meshgrid(xnew, y0, z0, indexing='ij')
input = np.asarray([x.ravel(), y.ravel(), z.ravel()]).T
out = fn(input)
out = out.reshape(len(xnew), len(y0), len(z0))
print(out.shape)
# (50, 22, 33)