如何使用Scipy和1D数组正确重塑N维插值的值?

时间:2019-03-11 13:14:02

标签: python scipy interpolation

提供一些数据

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D

x = [0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9,]
y = [0.01,0.01,0.01,0.255,0.255,0.255,0.5,0.5,0.5,0.01,0.01,0.01,0.255,0.255,0.255,0.5,0.5,0.5,0.01,0.01,0.01,0.255,0.255,0.255,0.5,0.5,0.5,]
z = [0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2]
v = [0.,0.,1.,0.,1.,1.,0.,1.,1.,0.,0.,0.,0.,0.5,1.,0.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.5,1.,]

fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
c = ax.scatter(x, y, z, c = v, s = 100, cmap = plt.cm.bwr, edgecolor = "black", alpha = 0.2)

ax.scatter(0.51, 0.32, 0.12, s = 100, c = "black", edgecolor = "black")

plt.show()

我想获得一个函数f(x,y,z),以找出值v在任意位置应该是什么。简单吧?那么,为什么我对scipy的热爱无法弄清楚该怎么做?

我发现的示例定义了x,y,z,定义了一些不错的网格,并进行了评估,以正确的形状和顺序获得了v。这是我的 尝试分解。如果所有数据最初都被格式化为一维怎么办?

我认为我能做

V = zeros((len(x),len(y),len(z)))
for i in range(len(x)):
    V[i, None, None] = v[i]
    for j in range(len(y)):
        V[None, j, None] = v[j]
        for k in range(len(z)):
            V[None, None, k] = v[k]

fn = RegularGridInterpolator((x,y,z), V)

但这返回ValueError: The points in dimension 0 must be strictly ascending

enter image description here

1 个答案:

答案 0 :(得分:1)

您要使用griddata,下面是使用数据的示例,

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
from scipy.interpolate import griddata
import numpy as np

x = [0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.46,0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9,]
y = [0.01,0.01,0.01,0.255,0.255,0.255,0.5,0.5,0.5,0.01,0.01,0.01,0.255,0.255,0.255,0.5,0.5,0.5,0.01,0.01,0.01,0.255,0.255,0.255,0.5,0.5,0.5,]
z = [0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2,0.,0.1,0.2]
v = [0.,0.,1.,0.,1.,1.,0.,1.,1.,0.,0.,0.,0.,0.5,1.,0.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.5,1.,]
points = np.array([x, y, z])

fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
c = ax.scatter(x, y, z, c=v, s = 100, cmap = plt.cm.bwr, edgecolor = "black", alpha = 0.2)

# This is the interpolation, use existing points and values (1D)
# to get the value at 0.51, 0.32, 0.12
p = griddata(points.T, v, (0.51, 0.32, 0.12))
ax.scatter(0.51, 0.32, 0.12, s=100, c=[p], cmap = plt.cm.bwr)

#Plot a meshgrid of interpolated values (optional)
pad = 0.02
xg = np.linspace(min(x)-pad, max(x)+pad,10)
yg = np.linspace(min(y)-pad, max(y)+pad,10)
zg = np.linspace(min(z)-pad, max(z)+pad,10)
X, Y, Z = np.meshgrid(xg, yg, zg)
vinterp = griddata(points.T, v, (X, Y, Z))
ci = ax.scatter(X.ravel(), Y.ravel(), Z.ravel(), c=vinterp.ravel(), s=10, cmap = plt.cm.bwr, edgecolor = "black", alpha = 0.2)

plt.show()

看起来像这样

enter image description here

带有绘制值网格以显示插值和示例点。