Scipy interpolation on a numpy array

后端 未结 1 1015
悲&欢浪女
悲&欢浪女 2020-12-14 22:44

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

       | <1    2    3    4    5+
-------|----------------------------
<10000 | 3.6   6.5  9.1          


        
相关标签:
1条回答
  • 2020-12-14 23:33

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

    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.

    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.

    So, to use map_coordinates, you need to turn your actual 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.

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

    0 讨论(0)
提交回复
热议问题