Traducir la interpolación de índice flotante de MATLAB a Python

Sep 08 2020

Por ejemplo, tengo una matriz de índice

ax = [0, 0.2, 2] #start from index 0: python

y matriz I

I= 
10    20    30    40    50
10    20    30    40    50
10    20    30    40    50
10    20    30    40    50
10    20    30    40    50

En MATLAB, ejecutando este código

[gx, gy] = meshgrid([1,1.2,3], [1,1.2,3]);
I = [10:10:50];
I = vertcat(I,I,I,I,I)
SI = interp2(I,gx,gy,'bilinear');

El resultado SIes

SI =
10    12    30
10    12    30
10    12    30

Intenté hacer la misma interpolación en Python, usando NumPy. Primero interpolo en filas, luego en columnas

import numpy as np
ax = np.array([0.0, 0.2, 2.0])
ay = np.array([0.0, 0.2, 2.0])
I = np.array([[10,20,30,40,50]])
I = np.concatenate((I,I,I,I,I), axis=0)
r_idx = np.arange(1, I.shape[0]+1)
c_idx = np.arange(1, I.shape[1]+1)
  
I_row = np.transpose(np.array([np.interp(ax, r_idx, I[:,x]) for x in range(0,I.shape[0])]))
I_col = np.array([np.interp(ay, c_idx, I_row[y,:]) for y in range(0, I_row.shape[0])])

SI = I_col

Sin embargo, el resultado SIes

SI =
10    10    20
10    10    20
10    10    20

¿Por qué mis resultados con Python son diferentes de los que usan MATLAB?

Respuestas

1 lpeak Sep 08 2020 at 16:56

Parece que se corrigió en exceso al pasar de MATLAB a Python, como se muestra en su primer extracto de código.

ax = [0, 0.2, 2] #start from index 0: python

En lógica numérica, esta secuencia no representa los índices sino la coordenada para que la función interpole. Como ya se encarga de incrementar la coordenada para que sea compatible con matlab aquí:

r_idx = np.arange(1, I.shape[0]+1)
c_idx = np.arange(1, I.shape[1]+1)

Puede reutilizar la misma coordenada de interpolación que usó en Matlab:

ax = [1,1.2,3]

Código completo:

import numpy as np
ax = np.array([1.0, 1.2, 3.0])
ay = np.array([1.0, 1.2, 3.0])
I = np.array([[10,20,30,40,50]])
I = np.concatenate((I,I,I,I,I), axis=0)
r_idx = np.arange(1, I.shape[0]+1)
c_idx = np.arange(1, I.shape[1]+1)

I_row = np.transpose(np.array([np.interp(ax, r_idx, I[:,x]) for x in range(0,I.shape[
0])]))
I_col = np.array([np.interp(ay, c_idx, I_row[y,:]) for y in range(0, I_row.shape[0])]
)

SI = I_col

y resultado:

array([[10., 12., 30.],
       [10., 12., 30.],
       [10., 12., 30.]])

Explicación sobre el error

Dado que axrepresenta las coordenadas de los dos primeros valores 0.0y 0.2estaban antes de la primera coordenada de r_idx. De acuerdo con la documentación , la interpolación estará por defecto en I [:, ​​x] [0].