Python 3d array interpolation extended

My question is decrypted by the code answer presented here: Interpolation of a 3d array in Python. How to avoid cycles? . The corresponding original solution code is below:

import numpy as np
from scipy.interpolate import interp1d
array = np.random.randint(0, 9, size=(100, 100, 100))
x = np.linspace(0, 100, 100)
x_new = np.linspace(0, 100, 1000)
new_array = interp1d(x, array, axis=0)(x_new)
new_array.shape # -> (1000, 100, 100)

The above approach works fine when x_new is a constant 1-dimensional array, but what if my x_new is not a constant 1-dimensional array, but depends on the latitude / longitude index in another 3-dimensional array. My x_new has a size of 355x195x192 (time x lat x long), and now I am twice per cycle in measuring latitude and longitude. Since x_new is different for each latitude / longitude pair, how can I avoid the loop as shown below? My cycle process takes a couple of hours, unfortunately ...

x_new=(np.argsort(np.argsort(modell, 0), 0).astype(float) + 1) / np.size(modell, 0)
## x_new is shape 355x195x192
## pobs is shape 355x1
## prism_aligned_tmax_sorted  is shape 355x195x192
interp_func = interpolate.interp1d(pobs, prism_aligned_tmax_sorted,axis=0)
tmaxmod = np.empty((355, 195, 192,))
tmaxmod[:] = np.NAN                                    
for latt in range(0, 195):
    for lonn in range(0, 192):
        temp = interp_func(x_new[:,latt,lonn])
        tmaxmod[:,latt,lonn] = temp[:,latt,lonn]

Thanks for any help!

+4
1

, , .

, interp1d , 1d-, .. F(x), x 2d- F. , , : (lat,lon). F_(lat,lon)(x).

, , , F(x) , , ( [lat,lon] , ). , , . , , .

. , , , , . , 3D- 2-, , 2d- . , , , . , , , .

, , :

import numpy as np
from scipy.interpolate import interp1d
arr = np.random.randint(0, 9, size=(3, 4, 5))
x = np.linspace(0, 10, 3)
x_new = np.random.rand(6,4,5)*10

## x is shape 3 
## arr is shape  3x4x5
## x_new is shape  6x4x5

# original, loopy approach
interp_func = interp1d(x, arr, axis=0)
res = np.empty((6, 4, 5))
for lat in range(res.shape[1]):
    for lon in range(res.shape[2]):
        temp = interp_func(x_new[:,lat,lon]) # shape (6,4,5) each iteration
        res[:,lat,lon] = temp[:,lat,lon]

# new, vectorized approach
arr2 = arr.reshape(arr.shape[0],-1) # shape (3,20)
interp_func2 = interp1d(x,arr2,axis=0)
x_new2 = x_new.reshape(x_new.shape[0],-1) # shape (6,20)
temp = interp_func2(x_new2) # shape (6,20,20): 20 larger than original!
s = x_new2.shape[1] # 20, used for fancy indexing ranges
res2 = temp[:,range(s),range(s)].reshape(res.shape) # shape (6,20) -> (6,4,5)

res res2 , , , . , , (nx,nlat,nlon) (nx,nlat*nlon,nlat*nlon), , , .


, , - : nlat*nlon . , , , , .

, ( interpolate.interpnd interpolate.griddata). , , , . , , , .


, , , , . , ( C), " 1- ". -

arr = arr.transpose(1,2,0) # shape (4,5,3)
interp_func = interp1d(x, arr, axis=-1)
...
for lat ...:
    for lon ...:
        res[lat,lon,:] = temp[lat,lon,:] # shape (4,5,6)

, , , res.transpose(2,0,1).

+1

Source: https://habr.com/ru/post/1673883/


All Articles