Jackie
Jackie

Reputation: 307

python - Extend 2-d array and interpolate the missing values

I have an array with size 48x80, now I want to extend the array in to a new one with size 117x192.
I have read about scipy.interpolate, but it doesn't mention about extending.

How can I extend the array and put the values into the new array?

FOR EXAMPLE: Given array A [[1,2,3],[4,5,6],[7,8,9]]

[1 2 3]
[4 5 6]
[7 8 9]

Now I want to extend array A to array B size 5x7

1 x 2 x 3
x x x x x
x x x x x
4 x 5 x 6
x x x x x
x x x x x
7 x 8 x 9

In which, replace these 'x' with interpolated values.

EXAMPLE 2: In more general array

[4 2 6 4]
[4 34 6 2]
[2 11 3 4]
[2 4 22 4]
[2 1 35 255]
[1 3 4 54]
[22 1 4 5]

What should I do if I want a new array in size 20x30

UPDATE: I figured out that there's a difference that makes @nicoguaro answer doesn't work in my case:

His solution:

pts = np.array([[i,j] for i in np.linspace(0,1,n) for j in np.linspace(0,1,m)] )
grid_x, grid_y = np.mgrid[0:1:m*2j, 0:1:n*2j]

My solution:

pts = np.array([[i,j] for i in np.linspace(0,2*m-1,m) for j in np.linspace(0,2*n-1,n)] )
grid_x, grid_y = np.mgrid[0:m*2, 0:n*2]

It leads to difference result. In fact, his solution works in most cases but TIFF file, I guess

Upvotes: 4

Views: 4149

Answers (1)

nicoguaro
nicoguaro

Reputation: 3871

Although interpolate does not have a function for this particular task, you can easily use the built-in option to do it. Using the same example that you propose

[1 2 3]
[4 5 6]
[7 8 9]

to

1 x 2 x 3
x x x x x
x x x x x
4 x 5 x 6
x x x x x
x x x x x
7 x 8 x 9

We can use this code

import numpy as np
import scipy.interpolate as inter
import matplotlib.pyplot as plt

A = np.array([[1,2,3],[4,5,6],[7,8,9]])
vals = np.reshape(A, (9))
pts = np.array([[i,j] for i in [0.0, 0.5, 1.0] for j in [0.0, 0.5, 1.0]] )
grid_x, grid_y = np.mgrid[0:1:7j, 0:1:5j]
grid_z = inter.griddata(pts, vals, (grid_x, grid_y), method='linear')

That gives as result

array([[ 1. ,  1.5,  2. ,  2.5,  3. ],
       [ 2. ,  2.5,  3. ,  3.5,  4. ],
       [ 3. ,  3.5,  4. ,  4.5,  5. ],
       [ 4. ,  4.5,  5. ,  5.5,  6. ],
       [ 5. ,  5.5,  6. ,  6.5,  7. ],
       [ 6. ,  6.5,  7. ,  7.5,  8. ],
       [ 7. ,  7.5,  8. ,  8.5,  9. ]])

or, as images

Original image

Interpolated image

In this case I used griddata that interpolates a set function (vals) defined over a set of points (pts) to a given rectilinear grid (given by grid_x and grid_y). If, for example, you want to use nx points for $x$ and ny for $y$, you can replace one line

grid_x, grid_y = np.mgrid[0:1:nx*1j, 0:1:ny*1j]

for nx=20 and ny=15 we got this image

enter image description here

You can see more examples at the documentation of the function.

Update: Including Example 2, where the matrix is

A = np.array([[4, 2, 6, 4],
            [4, 34, 6, 2],
            [2, 11, 3, 4],
            [2, 4, 22, 4],
            [2, 1, 35, 255],
            [1, 3, 4, 54],
            [22, 1, 4, 5]])

and for a new array of size 20x30. The code is below

import numpy as np
import scipy.interpolate as inter
import matplotlib.pyplot as plt

A = np.array([[4, 2, 6, 4],
            [4, 34, 6, 2],
            [2, 11, 3, 4],
            [2, 4, 22, 4],
            [2, 1, 35, 255],
            [1, 3, 4, 54],
            [22, 1, 4, 5]])
vals = np.reshape(A, (28))
pts = np.array([[i,j] for i in np.linspace(0,1,4) for j in np.linspace(0,1,7)] )
grid_x, grid_y = np.mgrid[0:1:20j, 0:1:30j]
grid_z = inter.griddata(pts, vals, (grid_x, grid_y), method='linear')

plt.matshow(A)
plt.matshow(grid_z)
plt.show()

The resulting images are: Example 2 Interpolated matrix in example 2

Upvotes: 6

Related Questions