MATLAB Examples

reshape_daily

reshape_daily reshapes daily time series from 1D to 3D or from 3D to 1D. 3D time series coordinates correspond to DAYSxMONTHSxYEARS and will always be 31x12xNUMBEROFYEARS. Missing data values and non-real days (e.g. April 31) are replaced by NaN when reshaping to 3D.

Contents

Syntax

[s,t]  = reshape_daily(s,t)
[s,t,year,month,day]  = reshape_daily(s,t)

Description

[s,t] = reshape_daily(s,t) returns reshaped time series arrays corresponding to time t and the signal s. If input arrays are Nx1 or 1xN, 3D arrays s and t are returned. If input arrays are 3D, Nx1 arrays are returned. Time array t must be in datenum format.

[s,t,year,month,day] = reshape_daily(s,t) also returns year, month, and day arrays corresponding to t.

Example 1: Daily time series of temperature data.

Consider the following data collected daily, with a few days of missing data.

t = (datenum(1937,3,5):datenum(1941,6,9))'; % daily time vector
t(105) = [];                                % missing measurements, perhaps
t(210:215) = [];                            % more missing data
temp = -12*cos(2*pi*t/365.25)+t*5e-4-280+rand(size(t));   % daily temperature data

figure
plot(t,temp,'b-')
datetick
xlabel('time')
ylabel('measured temprature ({\circ}F)')

Above we see our measurements. There seems to be a strong seasonal cycle, with a slight positive trend over the measurement period. Before we start analyzing this data, let's start by exploring the structure of the 3D output of reshape_daily. First, let's only look at days of the month.

[~,~,~,~,days] = reshape_daily(temp,t);

Each month has up to 31 days, there are 12 months in the year, and our data set contains data from five years, so our days matrix is 3D of dimensions 31x12x5. Each 31x12 matrix along dimension 3 is identical, so we will only look at days of the month from the first year:

days(:,:,1)
ans =

     1     1     1     1     1     1     1     1     1     1     1     1
     2     2     2     2     2     2     2     2     2     2     2     2
     3     3     3     3     3     3     3     3     3     3     3     3
     4     4     4     4     4     4     4     4     4     4     4     4
     5     5     5     5     5     5     5     5     5     5     5     5
     6     6     6     6     6     6     6     6     6     6     6     6
     7     7     7     7     7     7     7     7     7     7     7     7
     8     8     8     8     8     8     8     8     8     8     8     8
     9     9     9     9     9     9     9     9     9     9     9     9
    10    10    10    10    10    10    10    10    10    10    10    10
    11    11    11    11    11    11    11    11    11    11    11    11
    12    12    12    12    12    12    12    12    12    12    12    12
    13    13    13    13    13    13    13    13    13    13    13    13
    14    14    14    14    14    14    14    14    14    14    14    14
    15    15    15    15    15    15    15    15    15    15    15    15
    16    16    16    16    16    16    16    16    16    16    16    16
    17    17    17    17    17    17    17    17    17    17    17    17
    18    18    18    18    18    18    18    18    18    18    18    18
    19    19    19    19    19    19    19    19    19    19    19    19
    20    20    20    20    20    20    20    20    20    20    20    20
    21    21    21    21    21    21    21    21    21    21    21    21
    22    22    22    22    22    22    22    22    22    22    22    22
    23    23    23    23    23    23    23    23    23    23    23    23
    24    24    24    24    24    24    24    24    24    24    24    24
    25    25    25    25    25    25    25    25    25    25    25    25
    26    26    26    26    26    26    26    26    26    26    26    26
    27    27    27    27    27    27    27    27    27    27    27    27
    28    28    28    28    28    28    28    28    28    28    28    28
    29   NaN    29    29    29    29    29    29    29    29    29    29
    30   NaN    30    30    30    30    30    30    30    30    30    30
    31   NaN    31   NaN    31   NaN    31    31   NaN    31   NaN    31

With this structure in mind, it's easy to start asking questions about our data. Perhaps you'd like to know, what was the temperature on May 10th, 1939? Start by reshaping the data:

[temp3D,t3D] = reshape_daily(temp,t);

Now we have a 3D matrix containing to the temperature data, and another 3D matrix with corresponding dates. Missing data and non-real dates have been filled with NaN. 1939 is the third year of our data set, so the coordinates of May 10, 1939 will be DAY,MONTH,YEAR, or 10,5,3. See:

datestr(t3D(10,5,3))
ans =

10-May-1939

So, the temperature on May 10, 1939 is in the 3D temperature matrix here:

temp3D(10,5,3)
ans =

   79.7808

It was about 80 degrees that day. Sounds delightful. Is May 10th always this nice?

mean(temp3D(10,5,:))
ans =

   79.7532

std(temp3D(10,5,:))
ans =

    0.3797

Well, five years of data may not be enough for proper statistical analysis, but yes, it seems that May 10th tends to be real nice.

Daily values are often subject to high variability, so you may wish to look at the entire month of May. How did May temperatures look from 1937 to 1941?

MayTemps = squeeze(mean(temp3D(:,5,:)))

figure
plot(1937:1941,MayTemps,'-s')
xlabel('year')
ylabel('May monthly average temp')
MayTemps =

   80.2884
   80.4223
   80.5307
   80.7292
   80.9565

Perhaps you would like to look at all monthly averages. For this we'll use the nanmean function which is in the Statistics Toolbox. You can also find a similar version of nanmean here: http://www.mathworks.com/matlabcentral/fileexchange/6837

monthlyAvg = squeeze(nanmean(temp3D))

figure
plot(1937:1941,monthlyAvg,'-o')
legend('jan','feb','mar','apr','may','jun','july','aug','sept','oct','nov','dec')
xlabel('year')
ylabel('monthly average temperatures')
monthlyAvg =

       NaN   62.5993   62.7255   62.9494   63.0591
       NaN   64.1665   64.3837   64.4945   64.7655
   68.6635   68.4097   68.5203   68.9098   69.0135
   74.2630   74.4626   74.4896   74.9030   75.0827
   80.2884   80.4223   80.5307   80.7292   80.9565
   84.5445   84.7833   84.9414   85.1760   84.1798
   86.0997   86.4182   86.6034   86.6924       NaN
   84.5552   84.7987   84.8963   85.1269       NaN
   80.2348   80.3245   80.6865   80.7135       NaN
   73.6814   74.4581   74.6800   74.7186       NaN
   68.3297   68.5399   68.7864   68.9123       NaN
   63.9710   64.3024   64.3980   64.5967       NaN

Note that the first couple of months in 1937 have missing data, and the last several months in 1941 also have missing data. That's because we never had data for those months in the fist place. Also note that March of the first year shows a monthly average despite not have a full monthsworth of data. Same goes for June of 1941.

Example 2: From 3D to 1D.

To return back to columns of dates and data, simply feed those 3D matrices back into the reshape_daily function:

[temp1D,t1D] = reshape_daily(temp3D,t3D);

Now temp1D and t1D should be identical to the t and temp vectors we started with.

Author Info

This script was written by Chad A. Greene of the University of Texas Institute for Geophysics, May 2014. This function includes code from Jos van der Geest's insertrows v2, which can be found here: http://www.mathworks.com/matlabcentral/fileexchange/9984

See also

datenum, datevec, datestr, nanmean