我在 scipy 中使用 griddata 函数来插入 3 维和 4 维数据。它就像一个冠军,除了它返回一堆 NaN,因为我需要的一些点超出了输入数据的范围。鉴于 Nd 数据无论如何只适用于“线性”模式插值,让 griddata 进行外推而不是仅仅返回 NaN 应该很容易。有没有人这样做或找到解决方法?澄清一下:我有非结构化数据,所以我不能使用任何需要常规网格的功能。谢谢!亚历克斯
问问题
5334 次
2 回答
1
使用scipy.interpolate.Rbf插值和外插数据的一种可能性是 3、4 或实际上任何维度
为方便起见,get_data()
函数和plot_3d()
函数附在最后。
示例数据
示例数据如下所示(第四维 w,以颜色显示)。数据是不规则间隔的,没有网格化。
x, y, z, w = get_data(N=200)
plot_3d(x, y, z, w)
3d 插值和外推
首先,让我们设置新的 x 和 y 坐标。为了使这更有趣,让我们推断负 x 和负 y 方向。这形成了新的 x 和 y 感兴趣范围。
xs = np.linspace(-10, 20) # some extrapolation to negative numbers
ys = np.linspace(-10, 20) # some extrapolation to negative numbers
xnew, ynew = np.meshgrid(xs, ys)
xnew = xnew.flatten()
ynew = ynew.flatten()
使用scipy.interpolate.Rbf进行插值。现在,
from scipy.interpolate import Rbf
rbf3 = Rbf(x, y, z, function="multiquadric", smooth=5)
znew = rbf3(xnew, ynew)
plot_3d(xnew, ynew, znew)
- 可以有尽可能多的变量/维度。第一个参数 (
x
,y
) 被视为节点的坐标。参数之前的最后一个参数function
是要被插值的“值”(现在:)z
。 - 该
function
参数可用于控制如何插入值。这将影响结果,因此请使用您的数据。. - 该
smooth
参数可用于平滑数据中的一些噪声。如果smooth
为零,则结果为插值;它将遍历您的所有数据点。如果为正值,则数据更平滑。这将影响结果,因此请使用您的数据。. - 下面是结果,外推当然很差。这只是为了证明外推是可能的。您可能想要微调
function
并smooth
获得所需的结果。通常,不应“过多”推断数据(如本例所示)
添加第四维
也可以内插和外推到第四维。方法如下:
rbf4 = Rbf(x, y, z, w, function="thin_plate", smooth=5)
wnew = rbf4(xnew, ynew, znew)
plot_3d(xnew, ynew, znew, wnew)
附录:get_data
和plot_3d
出于测试目的:
import numpy as np
def get_data():
np.random.seed(100)
N = 200
maxval = 20
x = np.random.random(N) * maxval
y = np.random.random(N) * maxval
z = x ** 2 + np.sqrt(y) * y - y ** 3 + np.random.random(N) + 18 * y ** 2 * 2
w = x ** 2 - np.log(y + (x * y) ** 2)
return x, y, z, w
def plot_3d(x, y, z, w=None, show=True):
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
fig = plt.figure(figsize=(10, 6))
ax = axes3d.Axes3D(fig)
ax.scatter3D(x, y, z, c=w if not w is None else "b")
plt.show()
于 2020-12-04T21:31:14.973 回答
0
不太确定这是否适合您并且它尚不可用,但在 numpy 的开发版本中有一个“pad”数组功能......
https://github.com/numpy/numpy/blob/master/numpy/lib/arraypad.py
其中一个选项是“linear_ramp”,它从边缘值开始向外推断(填充)并线性增加/减少到指定的结束值。
它是一个纯 python 函数,所以你可以将它复制到你的路径中并导入(虽然未经我测试)
于 2012-07-07T05:51:17.893 回答