在numpy数组上的Scipy插值

时间:2022-08-26 21:25:37

I have a lookup table that is defined the following way:

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

       | <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] ])
  • The header row elements are (hh) < 1,2,3,4,5+
  • 头行元素为(hh) < 1,2,3,4,5+
  • The header column (inc) elements are <10000, 20000, 20001+
  • 头列(inc)元素<10000,20000,20001+

The user will input a value example (1.3, 25,000), (0.2, 50,000), so on. scipy.interpolate() should interpolate to determine the correct value.

用户将输入一个值示例(1.3、25,000)、(0.2、50,000)等等。插补()应该插入以确定正确的值。

Currently, the only way I can do this is with a bunch of if/elifs as exemplified below. I'm pretty sure there is a better, more efficient way of doing this

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

Here's what I've got so far:

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

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]) )

1 个解决方案

#1


8  

Edit: Updated things to reflect your clarifications above. Your question is much clearer now, thanks!

编辑:更新内容以反映你上面的澄清。你的问题现在清楚多了,谢谢!

Basically, you're just wanting to interpolate a 2D array at an arbitrary point.

基本上,你只是想在任意点插入一个二维数组。

scipy.ndimage.map_coordinates is what you want....

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

As I understand your question, you have a 2D array of "z" values that ranges from some xmin to xmax, and ymin to ymax in each direction.

正如我理解你的问题,你有一个二维的“z”值数组,范围从xmin到xmax,每个方向的ymin到ymax。

Anything outside of those bounding coordinates you want to return values from the edges of the array.

在这些边界坐标之外的任何东西都要从数组的边缘返回值。

map_coordinates has several options to handle points outside the boundaries of the grid, but none of them do exactly what you want. Instead, we can just set anything outside the boundaries to lie on the edge, and use map_coordinates as usual.

map_coordinate有几个选项可以处理网格边界之外的点,但它们都不会完全执行您想要的操作。相反,我们可以设置边界之外的任何东西,使其位于边缘,并像往常一样使用map_coordinate。

So, to use map_coordinates, you need to turn your actual coodinates:

因此,要使用map_coordinate,您需要将实际的coodinates:

       | <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

Into index coordinates:

成指数坐标:

       |  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

Note that your boundaries behave differently in each direction... In the x-direction, things behave smoothly, but in the y-direction, you're asking for a "hard" break, where y=20000 --> 3.9, but y=20000.000001 --> 4.5.

注意,你的边界在每个方向上都表现得不同……在x方向上,事情表现得很顺利,但在y方向上,你要求的是一个“硬”的break, y=20000——> 3.9,但是y=20000.000001——> 4.5。

As an example:

作为一个例子:

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

This yields:

这个收益率:

1.3 , 25000 --> 5.1807375
0.2 , 50000 --> 4.5
2.5 , 15000 --> 8.12252371652

Hopefully that helps...

希望这有助于…

#1


8  

Edit: Updated things to reflect your clarifications above. Your question is much clearer now, thanks!

编辑:更新内容以反映你上面的澄清。你的问题现在清楚多了,谢谢!

Basically, you're just wanting to interpolate a 2D array at an arbitrary point.

基本上,你只是想在任意点插入一个二维数组。

scipy.ndimage.map_coordinates is what you want....

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

As I understand your question, you have a 2D array of "z" values that ranges from some xmin to xmax, and ymin to ymax in each direction.

正如我理解你的问题,你有一个二维的“z”值数组,范围从xmin到xmax,每个方向的ymin到ymax。

Anything outside of those bounding coordinates you want to return values from the edges of the array.

在这些边界坐标之外的任何东西都要从数组的边缘返回值。

map_coordinates has several options to handle points outside the boundaries of the grid, but none of them do exactly what you want. Instead, we can just set anything outside the boundaries to lie on the edge, and use map_coordinates as usual.

map_coordinate有几个选项可以处理网格边界之外的点,但它们都不会完全执行您想要的操作。相反,我们可以设置边界之外的任何东西,使其位于边缘,并像往常一样使用map_coordinate。

So, to use map_coordinates, you need to turn your actual coodinates:

因此,要使用map_coordinate,您需要将实际的coodinates:

       | <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

Into index coordinates:

成指数坐标:

       |  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

Note that your boundaries behave differently in each direction... In the x-direction, things behave smoothly, but in the y-direction, you're asking for a "hard" break, where y=20000 --> 3.9, but y=20000.000001 --> 4.5.

注意,你的边界在每个方向上都表现得不同……在x方向上,事情表现得很顺利,但在y方向上,你要求的是一个“硬”的break, y=20000——> 3.9,但是y=20000.000001——> 4.5。

As an example:

作为一个例子:

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

This yields:

这个收益率:

1.3 , 25000 --> 5.1807375
0.2 , 50000 --> 4.5
2.5 , 15000 --> 8.12252371652

Hopefully that helps...

希望这有助于…