Python/Scipy 2D 插值(非均匀数据)
这是我上一篇文章的后续问题:Python/Scipy 插值 (map_coordinates)
假设我想在二维矩形区域上进行插值。我的变量“z”包含如下所示的数据。每列都具有恒定值,但是,数组的每一行可能具有不同的值,如下面的注释所示。
from scipy import interpolate
from numpy import array
import numpy as np
# # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309], # 0.0000, 0.0000, 0.0000, 0.0000
[-2.2818,-2.2818,-0.9309,-0.9309], # 0.2620, 0.2784, 0.3379, 0.3526
[-1.4891,-1.4891,-0.5531,-0.5531], # 0.6121, 0.6351, 0.7118, 0.7309
[-1.4891,-1.4891,-0.5531,-0.5531]]) # 1.0000, 1.0000, 1.0000, 1.0000
# Rows, Columns = z.shape
cols = array([0.0000, 0.1750, 0.8170, 1.0000])
rows = array([0.0000, 0.2620, 0.6121, 1.0000])
sp = interpolate.RectBivariateSpline(rows, cols, z, kx=1, ky=1, s=0)
xi = np.array([0.00000, 0.26200, 0.27840, 0.33790, 0.35260, 0.61210, 0.63510,
0.71180, 0.73090, 1.00000], dtype=np.float)
yi = np.array([0.000, 0.167, 0.815, 1.000], dtype=np.float)
print sp(xi, yi)
作为可视化这一点的另一种方式,我知道的值数组是:
rows = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526,
0.6121, 0.6351, 0.7118, 0.7309, 1.0000])
# # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309], # 0.0000
[-2.2818, ?, ?, ?], # 0.2620,
[ ?,-2.2818, ?, ?], # 0.2784
[ ?, ?,-0.9309, ?], # 0.3379
[ ? ,?, ?,-0.9309], # 0.3526
[-1.4891, ?, ?, ?], # 0.6121
[ ?,-1.4891, ?, ?], # 0.6351
[ ?, ?,-0.5531, ?], # 0.7118
[ ?, ?, ?,-0.5531], # 0.7309
[-1.4891,-1.4891,-0.5531,-0.5531]]) # 1.0000
我不知道“?”值,并且应该对它们进行插值。我尝试用 None 替换它们,但所有结果都得到“nan”。
编辑:
我想我需要使用“griddata”或“interp2”。 griddata 似乎产生了我期望的结果,但 'interp2' 没有。
from scipy import interpolate
from numpy import array
import numpy as np
z = array([[-2.2818,-2.2818,-0.9309,-0.9309],
[-2.2818,-2.2818,-0.9309,-0.9309],
[-1.4891,-1.4891,-0.5531,-0.5531],
[-1.4891,-1.4891,-0.5531,-0.5531]])
rows = array([0.0000, 0.0000, 0.0000, 0.0000,
0.2620, 0.2784, 0.3379, 0.3526,
0.6121, 0.6351, 0.7118, 0.7309,
1.0000, 1.0000, 1.0000, 1.0000])
cols = array([0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000])
xi = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526, 0.6121, 0.6351, 0.7118,
0.7309, 1.0000], dtype=np.float)
yi = array([0.000, 0.175, 0.818, 1.000], dtype=np.float)
GD = interpolate.griddata((rows, cols), z.ravel(),
(xi[None,:], yi[:,None]), method='linear')
I2 = interpolate.interp2d(rows, cols, z, kind='linear')
print GD.reshape(4, 10).T
print '\n'
print I2(xi, yi).reshape(4, 10).T
import matplotlib.pyplot as plt
import numpy.ma as ma
plt.figure()
GD = interpolate.griddata((rows.ravel(), cols.ravel()), z.ravel(),
(xi[None,:], yi[:,None]), method='linear')
CS = plt.contour(xi,yi,GD,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,GD,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)
plt.figure()
I2 = I2(xi, yi)
CS = plt.contour(xi,yi,I2,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,I2,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)
plt.show()
This is a follow-up question to my previous post: Python/Scipy Interpolation (map_coordinates)
Let's say I want to interpolate over a 2d rectangular area. My variable 'z' contains the data as shown below. Each column is at a constant value, however, each row of the array may be at a different value as shown in the comment below.
from scipy import interpolate
from numpy import array
import numpy as np
# # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309], # 0.0000, 0.0000, 0.0000, 0.0000
[-2.2818,-2.2818,-0.9309,-0.9309], # 0.2620, 0.2784, 0.3379, 0.3526
[-1.4891,-1.4891,-0.5531,-0.5531], # 0.6121, 0.6351, 0.7118, 0.7309
[-1.4891,-1.4891,-0.5531,-0.5531]]) # 1.0000, 1.0000, 1.0000, 1.0000
# Rows, Columns = z.shape
cols = array([0.0000, 0.1750, 0.8170, 1.0000])
rows = array([0.0000, 0.2620, 0.6121, 1.0000])
sp = interpolate.RectBivariateSpline(rows, cols, z, kx=1, ky=1, s=0)
xi = np.array([0.00000, 0.26200, 0.27840, 0.33790, 0.35260, 0.61210, 0.63510,
0.71180, 0.73090, 1.00000], dtype=np.float)
yi = np.array([0.000, 0.167, 0.815, 1.000], dtype=np.float)
print sp(xi, yi)
As another way of visualizing this, the array of values I KNOW would be:
rows = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526,
0.6121, 0.6351, 0.7118, 0.7309, 1.0000])
# # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309], # 0.0000
[-2.2818, ?, ?, ?], # 0.2620,
[ ?,-2.2818, ?, ?], # 0.2784
[ ?, ?,-0.9309, ?], # 0.3379
[ ? ,?, ?,-0.9309], # 0.3526
[-1.4891, ?, ?, ?], # 0.6121
[ ?,-1.4891, ?, ?], # 0.6351
[ ?, ?,-0.5531, ?], # 0.7118
[ ?, ?, ?,-0.5531], # 0.7309
[-1.4891,-1.4891,-0.5531,-0.5531]]) # 1.0000
I do not know the '?' values, and they should be interpolated. I tried replacing them with None, but then get 'nan' for all of my results.
EDIT:
I think I need to use either 'griddata' or 'interp2'. griddata seems to produce the result I expect, but 'interp2' does not.
from scipy import interpolate
from numpy import array
import numpy as np
z = array([[-2.2818,-2.2818,-0.9309,-0.9309],
[-2.2818,-2.2818,-0.9309,-0.9309],
[-1.4891,-1.4891,-0.5531,-0.5531],
[-1.4891,-1.4891,-0.5531,-0.5531]])
rows = array([0.0000, 0.0000, 0.0000, 0.0000,
0.2620, 0.2784, 0.3379, 0.3526,
0.6121, 0.6351, 0.7118, 0.7309,
1.0000, 1.0000, 1.0000, 1.0000])
cols = array([0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000])
xi = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526, 0.6121, 0.6351, 0.7118,
0.7309, 1.0000], dtype=np.float)
yi = array([0.000, 0.175, 0.818, 1.000], dtype=np.float)
GD = interpolate.griddata((rows, cols), z.ravel(),
(xi[None,:], yi[:,None]), method='linear')
I2 = interpolate.interp2d(rows, cols, z, kind='linear')
print GD.reshape(4, 10).T
print '\n'
print I2(xi, yi).reshape(4, 10).T
import matplotlib.pyplot as plt
import numpy.ma as ma
plt.figure()
GD = interpolate.griddata((rows.ravel(), cols.ravel()), z.ravel(),
(xi[None,:], yi[:,None]), method='linear')
CS = plt.contour(xi,yi,GD,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,GD,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)
plt.figure()
I2 = I2(xi, yi)
CS = plt.contour(xi,yi,I2,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,I2,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)
plt.show()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来你明白了。
在上面的代码示例和之前的(链接)问题中,您有结构化数据。可以使用 RectBivariateSpline 或 interp2d 进行插值。这意味着您拥有可以在网格上描述的数据(网格上的所有点都有一个已知值)。网格不一定必须具有相同的 dx 和 dy。 (如果所有 dx 和 dy 都相等,则您将拥有一个常规网格)
现在,您当前的问题询问如果并非所有点都已知该怎么办。这称为非结构化数据。您所拥有的只是字段中的点选择。您不一定能够构造所有顶点都具有已知值的矩形。对于这种类型的数据,您可以使用(已有的)
griddata
或某种BivariateSpline
。现在该选择哪个?
与结构化
RectBivariateSpline
最接近的类比是非结构化BivariateSpline
类:SmoothBivariateSpline
或LSQBivariateSpline
。如果您想使用样条线来插值数据,请使用这些。这使您的函数变得平滑且可微分,但您可以获得在 Z.max() 或 Z.min() 之外摆动的表面。由于您正在设置
ky=1
和kx=1
并且得到的结果我非常确定只是对结构化数据进行线性插值,所以我我个人只是从 RectBivariateSpline 样条线方案切换到interp2d
结构化网格插值方案。我知道文档说它适用于 常规网格,但是__doc__ 中的示例
本身只是结构化的,而不是常规的。如果您最终要切换,我很好奇您是否发现这些方法之间有任何显着差异。欢迎来到 SciPy。
Looks like you got it.
In your upper code example and in your previous (linked) question you have structured data. Which can be interpolated using
RectBivariateSpline
orinterp2d
. This means you have data that can be described on a grid (all points on the grid have a known value). The grid doesn't necessarily have to have all the same dx and dy. (if all dx's and dy's were equal, you'd have a Regular Grid)Now, your current question asks what to do if not all the points are known. This is known as unstructured data. All you have are a selection of points in a field. You can't necessarily construct rectangles where all vertices have known values. For this type of data, you can use (as you have)
griddata
, or a flavor ofBivariateSpline
.Now which to choose?
The nearest analogy to the structured
RectBivariateSpline
is one of the unstructuredBivariateSpline
classes:SmoothBivariateSpline
orLSQBivariateSpline
. If you want to use splines to interpolate the data, go with these. this makes your function smooth and differentiable, but you can get a surface that swings outside Z.max() or Z.min().Since you are setting
ky=1
andkx=1
and are getting what I am pretty sure is just linear interpolation on the structured data, I'd personally just switch from theRectBivariateSpline
spline scheme to theinterp2d
structured grid interpolation scheme. I know the documentation says it is for regular grids, but the example in the__doc__
itself is only structured, not regular.I'd be curious if you found any significant differences between the methods if you do end up switching. Welcome to SciPy.