在numpy数组上的Scipy插值

das*_*uki 10 python interpolation numpy scipy

我有一个查找表,其定义如下:

       | <1    2    3    4    5+
-------|----------------------------
<10000 | 3.6   6.5  9.1  11.5 13.8
20000  | 3.9   7.3  10.0 13.1 15.9
20000+ | 4.5   9.2  12.2 14.8 18.2


TR_ua1 = np.array([ [3.6, 6.5, 9.1, 11.5, 13.8],
                    [3.9, 7.3, 10.0, 13.1, 15.9],
                    [4.5, 9.2, 12.2, 14.8, 18.2] ])
Run Code Online (Sandbox Code Playgroud)
  • 标题行元素是(hh)<1,2,3,4,5+
  • 标题列(inc)元素<10000,20000,20001+

用户将输入值示例(1.3,25,000),(0.2,50,000),依此类推.scipy.interpolate()应进行插值以确定正确的值.

目前,我能做到这一点的唯一方法是使用一堆if/ elifs如下所示.我很确定有更好,更有效的方法

这是我到目前为止所得到的:

import numpy as np
from scipy import interpolate

if (ua == 1):
    if (inc <= low_inc):  # low_inc = 10,000
      if (hh <= 1):
        return TR_ua1[0][0]
      elif (hh >= 1 & hh < 2):
        return interpolate( (1, 2), (TR_ua1[0][1], TR_ua1[0][2]) )
Run Code Online (Sandbox Code Playgroud)

Joe*_*ton 8

编辑:更新了一些内容,以反映您的上述说明.你的问题现在更清楚了,谢谢!

基本上,您只是想在任意点插入2D数组.

scipy.ndimage.map_coordinates是你想要的....

据我了解你的问题,你有一个"z"值的二维数组,范围从某个xmin到xmax,每个方向的ymin到ymax.

您希望从数组边缘返回值的那些边界坐标之外的任何内容.

map_coordinates有几个选项来处理网格边界之外的点,但它们都没有完全符合您的要求.相反,我们可以设置边界之外的任何东西位于边缘,并像往常一样使用map_coordinates.

因此,要使用map_coordinates,您需要转换实际的坐标:

       | <1    2    3    4    5+
-------|----------------------------
<10000 | 3.6   6.5  9.1  11.5 13.8
20000  | 3.9   7.3  10.0 13.1 15.9
20000+ | 4.5   9.2  12.2 14.8 18.2
Run Code Online (Sandbox Code Playgroud)

进入索引坐标:

       |  0     1    2    3    4
-------|----------------------------
   0   | 3.6   6.5  9.1  11.5 13.8
   1   | 3.9   7.3  10.0 13.1 15.9
   2   | 4.5   9.2  12.2 14.8 18.2
Run Code Online (Sandbox Code Playgroud)

请注意,您的边界在每个方向上的行为都不同...在x方向上,事情表现得很顺利,但在y方向上,您要求"硬"中断,其中y = 20000 - > 3.9,但是y = 20000.000001 - > 4.5.

举个例子:

import numpy as np
from scipy.ndimage import map_coordinates

#-- Setup ---------------------------
z = np.array([ [3.6, 6.5, 9.1, 11.5, 13.8],
               [3.9, 7.3, 10.0, 13.1, 15.9],
               [4.5, 9.2, 12.2, 14.8, 18.2] ])
ny, nx = z.shape
xmin, xmax = 1, 5
ymin, ymax = 10000, 20000

# Points we want to interpolate at
x1, y1 = 1.3, 25000
x2, y2 = 0.2, 50000
x3, y3 = 2.5, 15000

# 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

# To deal with the "hard" break, we'll have to treat y differently, 
# so we're ust setting the min here...
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)

# Deal with the "hard" break in the y-direction
yi = (ny - 2) * (yi - ymin) / (ymax - ymin)
yi[yi > 1] = 2.0

# Now we actually interpolate
# map_coordinates does cubic interpolation by default, 
# use "order=1" to preform bilinear interpolation instead...
z1, z2, z3 = map_coordinates(z, [yi, xi])

# Display the results
for X, Y, Z in zip((x1, x2, x3), (y1, y2, y3), (z1, z2, z3)):
    print X, ',', Y, '-->', Z
Run Code Online (Sandbox Code Playgroud)

这会产生:

1.3 , 25000 --> 5.1807375
0.2 , 50000 --> 4.5
2.5 , 15000 --> 8.12252371652
Run Code Online (Sandbox Code Playgroud)

希望这有助于......