Isaac
Isaac

Reputation: 925

2 d interpolation with the arrays with different dimensions in python

I have three two dimesional arrays which have shape of (100,100). Each array looks like:

x =
[[-104.09417725 -104.08866882 -104.0831604  ..., -103.8795166  -103.87399292
-103.86849976]
..., 
[-104.11058044 -104.10507202 -104.09954834 ..., -103.89535522
-103.88983154 -103.88430786]
[-104.11141968 -104.10591125 -104.10038757 ..., -103.89614868 -103.890625
-103.88513184]]
y = 
[[ 40.81712341  40.81744385  40.81776428 ...,  40.82929611  40.82960129
40.82990646]
 ..., 
[ 40.98789597  40.9882164   40.98854065 ...,  41.00011063  41.00041199
41.00072479]]
z =
[[ 1605.58544922  1615.62341309  1624.33911133 ...,  1479.11254883
1478.328125    1476.13378906]
 ..., 
[ 1596.03857422  1600.5690918   1606.30712891 ...,  1598.56982422
1594.90454102  1594.07763672]]

Also I have two 1 d arrays of x1 and y1. These x1 and y1 are in the range of x and y respectively such as:

x1 = [ 104.07794  104.03169  104.03352  104.03584  104.03835  104.04085
104.04334  104.07315  104.07133  104.07635  104.07916  104.0321
104.03481  104.03741  104.04002  104.04366  104.04572  104.04787
...................................................................   
103.92937  103.89825  103.90027  103.90253  103.90352  103.90375
103.89922  103.89931  103.90145  103.90482  103.90885  103.91058
103.91243  103.91525  103.91785  103.92078  103.97814]
y1 = [ 40.9542   40.96922  40.96733  40.96557  40.96377  40.96218  40.96043
40.95446  40.95686  40.95296  40.95184  40.94984  40.94834  40.9469
40.94538  40.94287  40.94154  40.94008  40.93824  40.93705  40.93579
.........................................................................  
40.89675  40.9015   40.90044  40.89948  40.89766  40.89513  40.88374
40.88118  40.87915  40.87933  40.87917  40.878    40.87675  40.87598
40.87515  40.87421  40.91258]

x1 and y1 correspond as (x1,y1) each other following indices such as (104.07794,40.9542), (104.03169,40.96922) and so on. Here what I would like to get is z1 corresponding to (x1,y1) interpolated by x,y,z. For this purpose, I made a code like below:

x1,y1 = np.meshgrid(x1,y1)
f = interpolate.interp2d(x,y,z,kind='linear')
or
f = interpolate.Rbf(x,y,z,function='linear')
z1 = f(x1,y1)

However, I don't want to convert x1, y1 to 2 d meshgrid because this function fill the grid points which I don't like to fill in. So, I would like to interpolate x1, y1 without convert to 2 d meshgrid, but these 2d interpolation methods seem to require that x,y and x1,y1 have same dimesion. Is there any way to interpolate without making dimension of x1,y1 and x,y same? Thank you, Isaac

Upvotes: 1

Views: 2979

Answers (1)

hpaulj
hpaulj

Reputation: 231335

I'm not quite sure what you mean about x,y and x1,y1 have same dimesion.

I can construct an input set of data:

In [294]: x,y=np.meshgrid(np.arange(10),np.arange(8))    
In [295]: z=x+y

In [296]: f=interpolate.Rbf(x,y,z,kind='linear')

In [297]: x.shape
Out[297]: (8, 10)

I'm using meshgrid just because it is the easiest way to generate a pair of 2d arrays that make a resonable surface. As it is interp2d does not like working with this surface.

I can define another set of points as 2 1d arrays. The number of points has nothing to do with the number of ponts or layout of points defining the surface. I just have to give an (x1,y1) pair that corresponds to the (x,y,z) triplet that defines the surface.

In [298]: x1=np.linspace(0,10,15)
In [299]: y1=np.linspace(0,10,15)    
In [300]: f(x1,y1)
Out[300]: 
array([  1.78745907e-13,   1.42752327e+00,   2.85761392e+00,
         4.28560518e+00,   5.71422460e+00,   7.14293770e+00,
         8.57139192e+00,   1.00000000e+01,   1.14285329e+01,
         1.28573610e+01,   1.42852315e+01,   1.57040689e+01,
         1.70924026e+01,   1.84049594e+01,   1.95946258e+01])

The fact that x is 2d doesn't matter; I could flatten the inputs. The doc for interp2d specifically mentions doing this to multidimensional inputs.

 f1=interpolate.Rbf(x.flatten(), y.flatten(), z.flatten(), kind='linear')

The interpolation points could be arranged in a 2d shape as well

f(x1.reshape((3,5)), y1.reshape((3,5)))

same interpolated values, just arranged in a (3,5) array.


interp2d operates a bit different. It seems happier with 'cubic' than 'linear' (I haven't dug into why):

In [326]: f2=interpolate.interp2d(x,y,z,kind='cubic')    
In [327]: z1=f2(x1,y1)

In [328]: z1.shape
Out[328]: (15, 15)

The results is (x1.shape, y1.shape) - it treats the x1,y1 as defining a meshgrid like surface.

But I can extract the diagonal, and get essentially the same values as Rbf (except at the 2 ends):

In [329]: z1.diagonal()
Out[329]: 
array([  7.61803576e-18,   1.42857137e+00,   2.85714294e+00,
         4.28571419e+00,   5.71428543e+00,   7.14285905e+00,
         8.57142306e+00,   1.00000000e+01,   1.14287955e+01,
         1.28551995e+01,   1.41778962e+01,   1.54127554e+01,
         8.99313361e+00,   1.60000000e+01,   1.60000000e+01])

So with Rbf you specify exactly where you want it to interpolate the values, while interp2d you specify the x,y coordinates of the 2d space.

Upvotes: 2

Related Questions