Interpolación Scipy en una matriz numpy

Tengo una tabla de búsqueda que se define de la siguiente manera:

| <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] ]) 
  • Los elementos de la fila de encabezado son (hh) <1,2,3,4,5+
  • Los elementos de la columna de encabezado (inc) son <10000, 20000, 20001+

El usuario ingresará un ejemplo de valor (1.3, 25,000), (0.2, 50,000), etc. scipy.interpolate() debe interpolar para determinar el valor correcto.

Actualmente, la única forma en que puedo hacer esto es con un montón de if / elifs como se ilustra a continuación. Estoy bastante seguro de que hay una manera mejor y más eficiente de hacer esto

Esto es lo que tengo hasta ahora:

 import numpy as np from scipy import interpolate if (ua == 1): if (inc <= low_inc): # low_inc = 10,000 if (hh = 1 & hh < 2): return interpolate( (1, 2), (TR_ua1[0][1], TR_ua1[0][2]) ) 

Edición: Se actualizaron las cosas para reflejar sus aclaraciones anteriores. Tu pregunta es mucho más clara ahora, gracias!

Básicamente, solo quieres interpolar una matriz 2D en un punto arbitrario.

scipy.ndimage.map_coordinates es lo que quieres …

Según entiendo su pregunta, tiene una matriz 2D de valores “z” que varía de algunos xmin a xmax, y de ymin a ymax en cada dirección.

Cualquier cosa fuera de esas coordenadas de límite que desea devolver valores de los bordes de la matriz.

map_coordinates tiene varias opciones para manejar puntos fuera de los límites de la cuadrícula, pero ninguna de ellas hace exactamente lo que quieres. En su lugar, solo podemos establecer cualquier cosa fuera de los límites para que quede en el borde y usar map_coordinates como de costumbre.

Por lo tanto, para usar map_coordinates, debe activar sus coordenadas reales:

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

En las coordenadas del índice:

  | 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 

Tenga en cuenta que sus límites se comportan de manera diferente en cada dirección ... En la dirección x, las cosas se comportan sin problemas, pero en la dirección y, está pidiendo una ruptura "dura", donde y = 20000 -> 3.9, pero y = 20000.000001 -> 4.5.

Como ejemplo:

 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 

Esto produce:

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

Esperemos que eso ayude ...