2009-05-24 13 views
6

Tengo más de 20 tablas similares a la tabla 1. Donde todas las letras representan valores reales.Almacenamiento de datos para facilitar la interpolación de datos en Python

Table 1: 
$/cars |<1 | 2 | 3 | 4+ 
<10,000 | a | b | c | d 
20,000 | e | f | g | h 
30,000 | i | j | k | l 
40,000+ | m | n | o | p 

una entrada de usuario podría ser por ejemplo, (2,4, 24 594), que es un valor entre f, g, j, y k. La definición de función de My Python y el pseudocódigo para calcular esta interpolación bilineal es la siguiente.

def bilinear_interpolation(x_in, y_in, x_high, x_low, y_low, y_high): 
    # interpolate with respect to x 
    # interpolate with respect to y 
    # return result 

¿Cómo debo guardar los datos de la tabla 1 (un archivo, un diccionario, tupla de tuplas, o dict de listas), para que pueda realizar la interpolación bilineal más eficiente y correctamente?

Respuesta

7

Si desea la solución de mayor eficiencia computacional que pueda imaginar y no esté restringida a la biblioteca estándar, entonces recomendaría scipy/numpy. Primero, almacene la matriz a..p como una matriz numpy 2D y luego las matrices $ 4k-10k y 1-4 como matrices nude 1D. Utilice scipy's interpolate.interp1d si ambas matrices 1D son monótonamente crecientes, o interpolate.bsplrep (representación de spline bivariante) si no es así y sus matrices de ejemplo son tan pequeñas como su ejemplo. O simplemente escribe el tuyo y no te molestes con scipy. He aquí algunos ejemplos:

# this follows your pseudocode most closely, but it is *not* 
# the most efficient since it creates the interpolation 
# functions on each call to bilinterp 
from scipy import interpolate 
import numpy 
data = numpy.arange(0., 16.).reshape((4,4)) #2D array 
prices = numpy.arange(10000., 50000., 10000.) 
cars = numpy.arange(1., 5.) 
def bilinterp(price,car): 
    return interpolate.interp1d(cars, interpolate.interp1d(prices, a)(price))(car) 
print bilinterp(22000,2) 

La última vez que revisé (una versión de scipy de 2007-ish) sólo funcionaba para aumentar monótonamente matrices de X e Y)

para las pequeñas matrices como esta matriz 4x4 , Creo que desea utilizar esto: http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.bisplrep.html#scipy.interpolate.bisplrep que manejará superficies con formas más interesantes y la función solo necesita crearse una vez. Para matrices más grandes, creo que quieres esto (no estoy seguro si esto tiene las mismas restricciones que interp1d): http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp2d.html#scipy.interpolate.interp2d pero ambos requieren una estructura de datos diferente y más detallada que las tres matrices en el ejemplo anterior.

+0

por favor, dame algunos ejemplos, tengo un problema similar pero no puedo descifrarlo en O (log n) –

+0

Me gusta porque ya estoy usando numpy en mi aplicación: D gracias – dassouki

0

No hay nada especial acerca de la interpolación bilineal que hace que su caso de uso sea particularmente extraño; solo tiene que hacer dos búsquedas (para unidades de almacenamiento de filas/columnas completas) o cuatro búsquedas (para almacenamiento tipo array). El método más eficiente depende de sus patrones de acceso y la estructura de los datos.

Si su ejemplo es realmente representativo, con 16 entradas totales, puede almacenarlo como desee y será lo suficientemente rápido para cualquier tipo de cargas cuerdas.

3

Mantendré una lista ordenada de la primera columna y usaré el módulo bisect en la biblioteca estándar para buscar los valores; es la mejor manera de obtener los índices inmediatamente más bajos e inmediatamente más altos. Cada otra columna se puede mantener como otra lista paralela a esta.

Cuestiones relacionadas