Interpolation data to achieve gridded latitude and longitude when I have 360 month

1 view (last 30 days)
Behzad Navidi on 18 Feb 2020
Commented: Behzad Navidi on 19 Feb 2020
Hey all,
I have a table that has four columns (longitude, latitude, date, and observed_value). In my table latitude and longitude values represent 95 unique locations that are scattered randomly. Each one for 360 months; I mean I have 360 observed_value data for each unique location from like 1/1/1989, 2/1/1989, 3/1989, ... 12/1/2018. I want to convert this scattered data to gridded data by interpolation. I want to have data for longitude = 44.25:.5:63.75 and latitude: 24.25:.5:39.75 for each month. So, in the end, I will have so many locations rather than 95 (for example 11000) that have observed_data for these 360 months.
I have been thought about it for 2 days I really search for everything but I don't know how can I do this. I want to ask you please help me with the issue. If it is important, after that I want to make 1 x n cell which each array in it is a table for these gridded data locations for each month.
If you have any additional questions or require further clarification, please, do not hesitate to tell me.
I attached my table, any advice is highly appreciated, Thank you.

Jacob Wood on 18 Feb 2020
I believe the scatteredInterpolant() function is ideal for this case. This solution below is certainly not the fastest, but hopefully it is clear in how it achieves your goal.
dates = unique(mytable.date); %pick out the unique dates in the table
[new_lats,new_lons] = ndgrid(24.25:.5:39.75,44.25:.5:63.75); %make the grid for our new lats/lons
output_array = cell(1,numel(dates)); %make the output array we can store the newly interpolated data in
for ii = 1:numel(dates) %go through each month
%use logical indexing to select only the data for the relevant month
idx = mytable.date == dates(ii);
lats = mytable.lat(idx);
lons = mytable.lon(idx);
vals = mytable.observed_value(idx);
F = scatteredInterpolant(lats,lons,vals); %make interpolator object from unstructured data
new_vals = F(new_lats,new_lons); %apply interpolator at each new lat/lon
output_array{ii} = new_vals; %save the gridded data into a cell for this month
end

Behzad Navidi on 18 Feb 2020
Dear Jacob,
I'm very thankful to you for helping me with the question, really appreciate it. It's awesome. This code creates a 1x360 cell that each array represents a month. It's very nice. do you know it is possible to have all 360 months for each location as an array or not? I mean is this possible to use this output_array to achieve such a cell? 40 x 32 cell like this picture below.
40 longitude and 32 latitude so 40 x 32 = 1280 cell array and each array includes data for one location from 1/1/1989 to 12/1/2018, like this picture:
is this possible?
Thank you again
Best Regards????
Jacob Wood on 18 Feb 2020
It sure is! The cell array can be kind of a bugger to work with, so it is probably easier if we use a numerical array first and then collapse the dimensions as necessary. Note the changes to how we are implementing output_array:
output_array = NaN([size(new_lats) numel(dates)]);
for ii = 1:numel(dates)
idx = mytable.date == dates(ii);
lats = mytable.lat(idx);
lons = mytable.lon(idx);
vals = mytable.observed_value(idx);
F = scatteredInterpolant(lats,lons,vals);
new_vals = F(new_lats,new_lons);
output_array(:,:,ii) = new_vals;
end
Here we have a 32x40x360 array, which you can index into with typical Matlab indexing. For example, to look at the first 12 months of the most Southwest location:
output_array(1,1,1:12)
If the cell array you described above is more suitable for your needs you can collapse the 3rd dimension using num2cell():
num2cell(output_array,3)
And finally, to get rid of those pesky floating dimensions you can use squeeze:
output_cell_array = cellfun(@squeeze,num2cell(output_array,3),'UniformOutput',false);
Behzad Navidi on 19 Feb 2020
Dear Jacob,
I am so very thankful for your time. You fix my problem, I very much appreciate your help ?????.
Best Regards