pythoninterpolationlookup

Trouble figuring out input arguments to SciPy RegularGridInterpolator for 2D interpolation


I'm trying to interpolate 2D data to find the value of Z at point (X,Y) as if it were a 2D lookup table.

import numpy as np
import pandas as pd
from scipy.interpolate import RegularGridInterpolator
import io

xi, yi = 100, 100; # test points I want to evaluate the interpolator object at


# the 2D data copied from google sheets and pasted into Jupyter notebook generates this dataframe:
values = pd.read_csv(io.StringIO('''
  223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
  223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
  223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
  223,223,223,223,223,223,223,223,221,220,219,218,217,217,215,215,215,217,217,218,218,219,220,221,222,222,222
  223,223,223,223,223,223,223,223,223,219,218,217,215,215,210,210,210,215,217,217,217,218,219,220,221,222,222
  223,223,223,223,223,223,223,223,223,218,217,217,215,210,207,207,207,210,215,215,217,218,219,219,220,221,222
  223,223,223,223,223,223,223,223,218,217,223,215,210,207,205,205,207,207,210,210,215,217,218,219,220,221,222
  223,223,223,223,223,223,223,223,218,217,216,215,207,205,203,203,205,207,207,210,215,217,218,219,220,221,222
  223,223,223,223,223,223,223,223,218,217,216,215,207,205,203,203,205,207,210,212,215,217,218,219,220,221,222
  223,223,223,223,223,223,223,223,223,218,217,217,215,207,205,205,207,210,212,215,217,218,219,220,221,222,223
  223,223,223,223,223,223,223,223,223,223,218,218,217,215,207,207,215,215,215,217,218,219,220,221,222,223,223
  223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
  223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
  223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
  223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
  223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
  223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
  223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
  '''), header=None);

# these are the X and Y values corresponding to the X and Y dimensions of the data (values).
X = np.linspace(0, 2600, values.shape[1]);
Y = np.linspace(0, 1700, values.shape[0]);

Yi, Xi = np.meshgrid(Y, X);

interp = RegularGridInterpolator((Y, X), values); # X and Y are switched here because Y corresponds to the rows of the dataframe and X corresponds to the columns but I'm matching the SciPy syntax.

interp(np.array([[xi], [yi]]).T) # this is the portion I'm having trouble with

I don't understand what the format of the arguments I'm putting into the interp object. From the documentation, it says that the input is a tuple of ndarrays. But this example shows evaluating the interp object on a np.array and on a tuple of lists. I've tried those and a combination of everything between but I'm still not getting it right... thanks for your help.

The code as described above returns the following error:

InvalidIndexError: (array([1]), array([1]))

I'm trying to return the interpolation for a single point (every iteration of a for loop, for example). Or for all points at once after the for loop if it's necessary to do it that way.


Solution

  • The documentation you point to is using an array.

    You are using a dataframe. Based on 'How to perform interpolation on 2d grid from dataframe in python?', you can use the values attribute of the dataframe:

    import numpy as np
    import pandas as pd
    from scipy.interpolate import RegularGridInterpolator
    import io
    
    xi, yi = 100, 100; # test points I want to evaluate the interpolator object at
    
    
    # the 2D data copied from google sheets and pasted into Jupyter notebook generates this dataframe:
    values = pd.read_csv(io.StringIO('''
      223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
      223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
      223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
      223,223,223,223,223,223,223,223,221,220,219,218,217,217,215,215,215,217,217,218,218,219,220,221,222,222,222
      223,223,223,223,223,223,223,223,223,219,218,217,215,215,210,210,210,215,217,217,217,218,219,220,221,222,222
      223,223,223,223,223,223,223,223,223,218,217,217,215,210,207,207,207,210,215,215,217,218,219,219,220,221,222
      223,223,223,223,223,223,223,223,218,217,223,215,210,207,205,205,207,207,210,210,215,217,218,219,220,221,222
      223,223,223,223,223,223,223,223,218,217,216,215,207,205,203,203,205,207,207,210,215,217,218,219,220,221,222
      223,223,223,223,223,223,223,223,218,217,216,215,207,205,203,203,205,207,210,212,215,217,218,219,220,221,222
      223,223,223,223,223,223,223,223,223,218,217,217,215,207,205,205,207,210,212,215,217,218,219,220,221,222,223
      223,223,223,223,223,223,223,223,223,223,218,218,217,215,207,207,215,215,215,217,218,219,220,221,222,223,223
      223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
      223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
      223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
      223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
      223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
      223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
      223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223
      '''), header=None);
    
    # these are the X and Y values corresponding to the X and Y dimensions of the data (values).
    X = np.linspace(0, 2600, values.shape[1]);
    Y = np.linspace(0, 1700, values.shape[0]);
    
    Yi, Xi = np.meshgrid(Y, X);
    
    interp = RegularGridInterpolator((Y, X), values.values); # X and Y are switched here because Y corresponds to the rows of the dataframe and X corresponds to the columns but I'm matching the SciPy syntax.
    

    Alternatively, you can convert the DataFrame to a numpy array and then. transpose the array to match the expected shape, (Y, X), with the addition of values_array = values.to_numpy().T and then adjusting the interpolation call too interp = RegularGridInterpolator((X, Y), values_array).