问题描述
我正在尝试使用scipy进行插值.我已经看了很多例子,但是找不到我想要的东西.
I'm trying to do some interpolation with scipy. I've gone through many examples, but I'm not finding exactly what I want.
假设我有一些数据,其中行和列变量的范围可以从0到1.每行和列之间的增量变化并不总是相同的(见下文).
Let's say I have some data where the row and column variable can vary from 0 to 1. The delta changes between each row and column is not always the same (see below).
| 0.00 0.25 0.80 1.00
------|----------------------------
0.00 | 1.40 6.50 1.50 1.80
0.60 | 8.90 7.30 1.10 1.09
1.00 | 4.50 9.20 1.80 1.20
现在,我希望能够获取一组x,y点并确定插值.我知道我可以使用map_coordinates完成此操作.我想知道是否有任何简单/聪明的方法来将x,y值设为数据数组中的适当索引.
Now I want to be able to take a set of x,y points and determine the interpolated values. I know I can do this with map_coordinates. I'm wondering if there is any easy/clever way to make an x,y value to the appropriate index in the data array.
例如,如果我输入x,y = 0.60,0.25,那么我应该找回要插值的正确索引.在这种情况下,这将是1.0、1.0,因为0.60、0.25会精确地映射到第二行和第二列. x = 0.3将映射到0.5,因为它介于0.00和0.60之间.
For example, if I input x,y = 0.60, 0.25, then I should get back the correct index to be interpolated. In this case, that would be 1.0, 1.0 since 0.60, 0.25 would map exactly to the second row and second column. x=0.3 would map to 0.5 since it is halfway between 0.00 and 0.60.
我知道如何获得想要的结果,但是我可以肯定,有一个非常快速/清晰的一两个直线(或已经存在的函数)可以使我的代码更加清晰.基本上,它需要在某些数组之间进行分段插值.
I know how to get the result I want, but I feel certain that there is a very quick/clear one or two-liner (or function that already exists) that can do this to make my code more clear. Basically it needs to piecewise interpolate between some array.
这里是一个示例(主要基于在numpy数组上进行Scipy插值的代码)-我将TODO放到该新功能所在的位置:
Here is an example (based heavily on the code from Scipy interpolation on a numpy array) - I put TODO where this new function would go:
from scipy.ndimage import map_coordinates
from numpy import arange
import numpy as np
# 0.000, 0.175, 0.817, 1.000
z = array([ [ 3.6, 6.5, 9.1, 11.5], # 0.0000
[ 3.9, -7.3, 10.0, 13.1], # 0.2620
[ 1.9, 8.3, -15.0, -12.1], # 0.6121
[-4.5, 9.2, 12.2, 14.8] ]) # 1.0000
ny, nx = z.shape
xmin, xmax = 0., 1.
ymin, ymax = 0., 1.
xrange = array([0.000, 0.175, 0.817, 1.000 ])
yrange = array([0.0000, 0.2620, 0.6121, 1.0000])
# Points we want to interpolate at
x1, y1 = 0.20, 0.45
x2, y2 = 0.30, 0.85
x3, y3 = 0.95, 1.00
# To make our lives easier down the road, let's
# turn these into arrays of x & y coords
xi = np.array([x1, x2, x3], dtype=np.float)
yi = np.array([y1, y2, y3], dtype=np.float)
# Now, we'll set points outside the boundaries to lie along an edge
xi[xi > xmax] = xmax
xi[xi < xmin] = xmin
yi[yi > ymax] = ymax
yi[yi < ymin] = ymin
# We need to convert these to (float) indicies
# (xi should range from 0 to (nx - 1), etc)
xi = (nx - 1) * (xi - xmin) / (xmax - xmin)
yi = (ny - 1) * (yi - ymin) / (ymax - ymin)
# TODO: Instead, xi and yi need to be mapped as described. This can only work with
# even spacing...something like:
#xi = SomeInterpFunction(xi, xrange)
#yi = SomeInterpFunction(yi, yrange)
# Now we actually interpolate
# map_coordinates does cubic interpolation by default,
# use "order=1" to preform bilinear interpolation instead...
print xi
print yi
z1, z2, z3 = map_coordinates(z, [yi, xi], order=1)
# Display the results
for X, Y, Z in zip((x1, x2, x3), (y1, y2, y3), (z1, z2, z3)):
print X, ',', Y, '-->', Z
推荐答案
我认为您需要矩形结构化网格上的二元样条线:
import numpy
from scipy import interpolate
x = numpy.array([0.0, 0.60, 1.0])
y = numpy.array([0.0, 0.25, 0.80, 1.0])
z = numpy.array([
[ 1.4 , 6.5 , 1.5 , 1.8 ],
[ 8.9 , 7.3 , 1.1 , 1.09],
[ 4.5 , 9.2 , 1.8 , 1.2 ]])
# you have to set kx and ky small for this small example dataset
# 3 is more usual and is the default
# s=0 will ensure this interpolates. s>0 will smooth the data
# you can also specify a bounding box outside the data limits
# if you want to extrapolate
sp = interpolate.RectBivariateSpline(x, y, z, kx=2, ky=2, s=0)
sp([0.60], [0.25]) # array([[ 7.3]])
sp([0.25], [0.60]) # array([[ 2.66427408]])
这篇关于Python/Scipy插值(map_coordinates)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!