2

I have Python dictionaries that look like this:

a = {0.0 : {0.0: 343, 0.5: 23, 1.0: 34, 1.5: 9454, ...}, 0.5 : {0.0: 359, 0.5: -304, ...}, ...}

So they are 2D dictionaries that resemble 2D grids of m * n elements.

The values are evenly distributed, but the dictionaries may have different "resolutions". For instance, in the above example the values are separated by 0.5. Another dictionary has the separation of 1.0. Further, the range of the values is also variable, for example:

  • one dictionary has the x range from -50.0 to 50.0, and y from -60.0 to 60.0, with a resolution of 0.5
  • second dictionary has the x range from -100.0 to 100.0, y from -100.0 to 100.0, with a resolution of 5.0

I need to create a function that takes a 2D value (e.g. 3.49, 20.31) and returns the interpolated value in the grid.

How to do that?

I guess it'd help to first convert this form to a Numpy array, but I don't know how to do it.

Edit:

  • the input 2D values will always be in the grid, they cannot be outside its range.
  • I have no preference for the interpolation method, a linear interpolation method is fine.
flotr
  • 165
  • 1
  • 1
  • 8
  • Do you know that the 2D value will actually be in the grid? Or could it be outside the range defined by the dictionaries? – David Z Jan 11 '15 at 20:24
  • They will always be in the grid, they cannot be outside its range. – flotr Jan 11 '15 at 20:26
  • Possibly related: http://scicomp.stackexchange.com/questions/2641, http://scicomp.stackexchange.com/questions/16432. Also [this](http://denis-bz.github.io/docs/intergrid.html) looks promising but I've never used it. – David Z Jan 11 '15 at 20:31

1 Answers1

2

With a sample dictionary, I constructed the required numpy arrays, x, y, and 2d z. And then used a scipy interpolator to do the rest.

import numpy as np

a = {0.0 : {0.0: 0, 0.5: 3, 1.0: 6, 1.5: 9},
 0.5 : {0.0: 1, 0.5: 5, 1.0: 9, 1.5: 13},
 1.0 : {0.0: 2, 0.5: 7, 1.0: 12, 1.5: 17},
 1.5 : {0.0: 3, 0.5: 9, 1.0: 15, 1.5: 21},
 2.0 : {0.0: 4, 0.5: 11, 1.0: 18, 1.5: 25},
    }
print a
x = np.array(sorted(a.keys()))   # dictionary keys might not be sorted
print x
y = np.array(sorted(a[x[0]].keys()))
print y
z = np.zeros((len(x),len(y)))
for i,m in enumerate(x):
    for j,n in enumerate(y):   # assumes nested keys are all the same
        z[i,j] = a[m][n]
print z

Note that these arrays look a lot like lists, or lists of lists.

from scipy import interpolate
f = interpolate.interp2d(y,x,z,kind='linear') #  columns, rows, data
print f([0,.25,.5,.75],[0,.25,.5,.75])

producing:

{0.0: {0.0: 0, 0.5: 3, 1.5: 9, 1.0: 6}...}}  # dict

[ 0.   0.5  1.   1.5  2. ]   # x
[ 0.   0.5  1.   1.5]    # y
[[  0.   3.   6.   9.]   # z
 [  1.   5.   9.  13.]
 [  2.   7.  12.  17.]
 [  3.   9.  15.  21.]
 [  4.  11.  18.  25.]]

[[  0.     1.5    3.     4.5    6.  ]
 [  0.5    2.25   4.     5.75   7.5 ]
 [  1.     3.     5.     7.     9.  ]
 [  1.5    3.75   6.     8.25  10.5 ]
 [  2.     4.5    7.     9.5   12.  ]]

http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.interpolate.interp2d.html

hpaulj
  • 221,503
  • 14
  • 230
  • 353