Reputation: 925
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
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