0

Linear interpolation in python is possible by the function pandas.interpolate. However it does not support decimal indexing and we have to round off to the nearest integer index. As January has 31 days, the exact mid point value is 15.5. In python, I'm unable to assign the value of January average value to the 15.5 position. February has it's midpoint 45th day and thus it is possible to assign February average value to 45th index. I have a monthly dataset that has 12 values, one for each month for every combination of latitude and longitude. Shape of the dataset-

print(db.shape)
(12, 192, 288)

Values of a random selected latitude longitude for each month-

<xarray.DataArray 'RAIN' (time: 12)>
array([2.134660e-22, 2.385684e-22, 3.569678e-23, 2.779505e-24, 2.987041e-23,
       1.156274e-21, 7.076990e-22, 9.011676e-25, 0.000000e+00, 0.000000e+00,
       1.311926e-22, 4.365676e-23], dtype=float32)

I used the resample.interpolate function with following arguments-

da=db.resample(time='1D').interpolate('linear')

Result for the same latitude and longitude-

<xarray.DataArray 'RAIN' (time: 335)>
array([2.13465963e-22, 2.14275718e-22, 2.15085473e-22, 2.15895229e-22,
       2.16704984e-22, 2.17514739e-22, 2.18324494e-22, 2.19134250e-22,
       2.19944005e-22, 2.20753760e-22, 2.21563515e-22, 2.22373270e-22,
       2.23183026e-22, 2.23992781e-22, 2.24802536e-22, 2.25612291e-22,
       2.26422047e-22, 2.27231802e-22, 2.28041557e-22, 2.28851312e-22,
       2.29661068e-22, 2.30470823e-22, 2.31280578e-22, 2.32090333e-22,
       2.32900089e-22, 2.33709844e-22, 2.34519599e-22, 2.35329354e-22,
       2.36139109e-22, 2.36948865e-22, 2.37758620e-22, 2.38568375e-22,
       2.31322961e-22, 2.24077547e-22, 2.16832132e-22, 2.09586718e-22,
       2.02341304e-22, 1.95095890e-22, 1.87850475e-22, 1.80605061e-22,
       1.73359647e-22, 1.66114233e-22, 1.58868819e-22, 1.51623404e-22,
       1.44377990e-22, 1.37132576e-22, 1.29887162e-22, 1.22641747e-22,
       1.15396333e-22, 1.08150919e-22, 1.00905505e-22, 9.36600903e-23,
       8.64146761e-23, 7.91692618e-23, 7.19238476e-23, 6.46784333e-23,
       5.74330191e-23, 5.01876049e-23, 4.29421906e-23, 3.56967764e-23,
       3.46349350e-23, 3.35730873e-23, 3.25112396e-23, 3.14493919e-23,
       3.03875442e-23, 2.93256965e-23, 2.82638488e-23, 2.72020011e-23,
       2.61401534e-23, 2.50783057e-23, 2.40164580e-23, 2.29546103e-23,
       2.18927626e-23, 2.08309149e-23, 1.97690672e-23, 1.87072195e-23,
       1.76453718e-23, 1.65835241e-23, 1.55216764e-23, 1.44598287e-23,
       1.33979810e-23, 1.23361333e-23, 1.12742856e-23, 1.02124379e-23,
       9.15059025e-24, 8.08874255e-24, 7.02689486e-24, 5.96504716e-24,
       4.90319946e-24, 3.84135177e-24, 2.77950407e-24, 3.68253488e-24,
       4.58556510e-24, 5.48859532e-24, 6.39162554e-24, 7.29465576e-24,
       8.19768598e-24, 9.10071620e-24, 1.00037464e-23, 1.09067766e-23,
       1.18098069e-23, 1.27128371e-23, 1.36158673e-23, 1.45188975e-23,
       1.54219277e-23, 1.63249580e-23, 1.72279882e-23, 1.81310184e-23,
       1.90340486e-23, 1.99370788e-23, 2.08401091e-23, 2.17431393e-23,
       2.26461695e-23, 2.35491997e-23, 2.44522299e-23, 2.53552602e-23,
       2.62582904e-23, 2.71613206e-23, 2.80643508e-23, 2.89673810e-23,
       2.98704112e-23, 6.62060109e-23, 1.02541611e-22, 1.38877211e-22,
       1.75212812e-22, 2.11548412e-22, 2.47884012e-22, 2.84219612e-22,
       3.20555212e-22, 3.56890813e-22, 3.93226413e-22, 4.29562013e-22,
       4.65897613e-22, 5.02233213e-22, 5.38568814e-22, 5.74904414e-22,
       6.11240014e-22, 6.47575614e-22, 6.83911214e-22, 7.20246815e-22,
       7.56582415e-22, 7.92918015e-22, 8.29253615e-22, 8.65589216e-22,
       9.01924816e-22, 9.38260416e-22, 9.74596016e-22, 1.01093162e-21,
       1.04726722e-21, 1.08360282e-21, 1.11993842e-21, 1.15627402e-21,
       1.14132149e-21, 1.12636899e-21, 1.11141649e-21, 1.09646399e-21,
       1.08151149e-21, 1.06655899e-21, 1.05160649e-21, 1.03665399e-21,
       1.02170148e-21, 1.00674898e-21, 9.91796481e-22, 9.76843980e-22,
       9.61891479e-22, 9.46938977e-22, 9.31986476e-22, 9.17033975e-22,
       9.02081474e-22, 8.87128972e-22, 8.72176471e-22, 8.57223970e-22,
       8.42271469e-22, 8.27318967e-22, 8.12366466e-22, 7.97413965e-22,
       7.82461464e-22, 7.67508962e-22, 7.52556461e-22, 7.37603960e-22,
       7.22651459e-22, 7.07698957e-22, 6.84899028e-22, 6.62099098e-22,
       6.39299169e-22, 6.16499239e-22, 5.93699310e-22, 5.70899381e-22,
       5.48099451e-22, 5.25299522e-22, 5.02499592e-22, 4.79699663e-22,
       4.56899733e-22, 4.34099804e-22, 4.11299874e-22, 3.88499945e-22,
       3.65700015e-22, 3.42900086e-22, 3.20100157e-22, 2.97300227e-22,
       2.74500298e-22, 2.51700368e-22, 2.28900439e-22, 2.06100509e-22,
       1.83300580e-22, 1.60500650e-22, 1.37700721e-22, 1.14900791e-22,
       9.21008620e-23, 6.93009326e-23, 4.65010031e-23, 2.37010737e-23,
       9.01144211e-25, 8.72097659e-25, 8.43027737e-25, 8.13957815e-25,
       7.84887893e-25, 7.55817971e-25, 7.26748049e-25, 6.97678127e-25,
       6.68608205e-25, 6.39538283e-25, 6.10468361e-25, 5.81398439e-25,
       5.52328517e-25, 5.23258595e-25, 4.94188673e-25, 4.65118751e-25,
       4.36048830e-25, 4.06978908e-25, 3.77908986e-25, 3.48839064e-25,
       3.19769142e-25, 2.90699220e-25, 2.61629298e-25, 2.32559376e-25,
       2.03489454e-25, 1.74419532e-25, 1.45349610e-25, 1.16279688e-25,
       8.72097659e-26, 5.81398439e-26, 2.90699220e-26, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
       0.00000000e+00, 0.00000000e+00, 4.23202032e-24, 8.46404064e-24,
       1.26960610e-23, 1.69280813e-23, 2.11601016e-23, 2.53921219e-23,
       2.96241422e-23, 3.38561625e-23, 3.80881829e-23, 4.23202032e-23,
       4.65522235e-23, 5.07842438e-23, 5.50162641e-23, 5.92482845e-23,
       6.34803048e-23, 6.77123251e-23, 7.19443454e-23, 7.61763657e-23,
       8.04083860e-23, 8.46404064e-23, 8.88724267e-23, 9.31044470e-23,
       9.73364673e-23, 1.01568488e-22, 1.05800508e-22, 1.10032528e-22,
       1.14264549e-22, 1.18496569e-22, 1.22728589e-22, 1.26960610e-22,
       1.31192630e-22, 1.28274767e-22, 1.25356905e-22, 1.22439042e-22,
       1.19521180e-22, 1.16603317e-22, 1.13685455e-22, 1.10767592e-22,
       1.07849730e-22, 1.04931867e-22, 1.02014005e-22, 9.90961425e-23,
       9.61782800e-23, 9.32604175e-23, 9.03425550e-23, 8.74246926e-23,
       8.45068301e-23, 8.15889676e-23, 7.86711051e-23, 7.57532426e-23,
       7.28353801e-23, 6.99175176e-23, 6.69996552e-23, 6.40817927e-23,
       6.11639302e-23, 5.82460677e-23, 5.53282052e-23, 5.24103427e-23,
       4.94924802e-23, 4.65746177e-23, 4.36567553e-23])

Here you can see that it assigns each value as the 1st of the month and then interpolates it. I want to place the first value as the value of index 15.5 (31/2) for January. Basically I want to pass this array(/ 15.5, 45, 74.5, 105, 135.5, 166 ,196.5, 227.5, 258, 288.5, 319 ,349.5/) as an index for the 12 values of each month and then interpolate it.

Is there any function that can assign interdecimal values for linear interpolation in python?

  • Interpolation of time series data in pandas and xarray is quite flexible, so I'm guessing what you are looking for should be possible. Could you be a little more specific regarding where your trouble is, maybe in posting an example of what you have tried? Are you trying to interpolate data to month midpoints? Or, do you have data defined at month midpoints and are trying to interpolate between those values to generate a daily time series? – spencerkclark Feb 03 '20 at 12:17
  • Just edited the question with an example and the requirement. Also linear interpolation in resampling.interpolate only does interpolations between the dates specified. In my case it is interpolating from Jan 1st till Dec 1st i.e. 335 days. However I want values for the entire year. Is there any other way of achieving this? – Krishna Kashiv Feb 04 '20 at 17:44
  • What does the time coordinate on the original DataArray look like? It sounds like it represents the first of each month? You may need to overwrite this coordinate if you want it to represent the midpoint of each month. Regarding values outside the range of the original dates, xarray supports extrapolation, though you would need to go through the generic `interp` method rather than use `resample`. If the original array is periodic (meaning that this a climatology in some sense) you would probably need to artificially add a wraparound January of the following year to do the interpolation. – spencerkclark Feb 05 '20 at 11:36

1 Answers1

1

For linear interpolation you could use scipy.interpolate.interp1d:

Here's an example using your specified index, wrapping it around so as to get the Dec-Jan values. I've used random values for data and a data shape of (365,4,4) to make the result easier to plot.

import scipy as sp, numpy as np, matplotlib.pyplot as plt

index = [15.5, 45, 74.5, 105, 135.5, 166 ,196.5, 227.5, 258, 288.5, 319 ,349.5]
nx, ny = 4, 4
data = np.random.randn(12,nx,ny)

index_wrapped = [index[-1]-365] + index + [365+index[0]]
data_wrapped = np.concatenate((np.array([data[-1]]), data, np.array([data[0]])))

new_index = np.arange(0,365)
new_data = np.zeros((365,nx,ny))

i=1
for x in [0,1]:
    for y in [0,1]:

        f = sp.interpolate.interp1d(index_wrapped,data_wrapped[:,x,y])
        new_data[:,x,y] = f(new_index)
        
        plt.subplot(2,2,i)
        plt.plot(new_data[:,x,y],'bo',alpha=0.2)
        plt.plot(index, data[:,x,y],'ro')
        i+=1
plt.show()

enter image description here

If you didn't need linear interpolation, scipy.signal.resample uses a fourier series, so has the wrap-around built-in.

Noah Smith
  • 63
  • 6