Emma
Emma

Reputation: 618

find range between two specific times in matlab

I have an annual data set:

Jday = datenum('2009-01-01 00:00','yyyy-mm-dd HH:MM'):1/24:...
    datenum('2009-12-31 23:00','yyyy-mm-dd HH:MM');
DateV = datevec(Jday);
dat = 1+(10-1).*rand(length(Jday),10);
noise = 10*sin(2*pi*Jday/32)+20;
for i = 1:size(dat,2);
    dat2(:,i) = dat(:,i)+noise';
end

which represents temperature measurements recorded through a water column. I would like to calculate the temperature range between 06:00 and 18:00 for each day so that I end up with 365 values for each depth so a final matrix of 365x10.

I can specify the individual days by:

[~,~,b] = unique(DateV(:,2:3),'rows');

But I cant work out how to only consider values recorded between 06:00 am and 18:00 pm. Could anyone provide some information about the best possible way of doing this?

Amended: slightly long answer

Jday = datenum('2009-01-01 00:00','yyyy-mm-dd HH:MM'):1/24:...
    datenum('2009-12-31 23:00','yyyy-mm-dd HH:MM');
DateV = datevec(Jday);
dat = 1+(10-1).*rand(length(Jday),10);
noise = 10*sin(2*pi*Jday/32)+20;
for i = 1:size(dat,2);
    dat2(:,i) = dat(:,i)+noise';
end

for i = 1:size(dat2,2);
    data = [DateV(:,4),dat2(:,i)]; % obtain all hours from DateV array

    dd = find(data(:,1) == 6); % find 06:00
    dd(:,2) = find(data(:,1) == 18); % find 18:00

    for ii = 1:size(dd,1);
        result(ii,i) = range(data(dd(ii,1):dd(ii,2),2)); % calculate range
    end
end

Upvotes: 0

Views: 1876

Answers (2)

baraujo
baraujo

Reputation: 21

Hourly date range between 01-Jan-1987 and 31-Dec-1987:

start_date = datenum(1987,01,01,00,00,00)
end_date = datenum(1987,12,31,23,00,00)
interval = datenum(1987,0,0,1,0,0)-datenum(1987,0,0,0,0,0) % 1 hour interval

date_range = [start_date:interval:end_date]

Very simple and works also for leap years.

Upvotes: 2

Eitan T
Eitan T

Reputation: 32930

If range is fed with a matrix, it operates on each column independently. We can use this to prepare a matrix where each column contains the values for the time interval of 06:00 to 18:00, and apply range.

  1. The tricky part is manipulating your 365x24-by-10 matrix to get the columns right:

    A = permute(reshape(dat2', [10, 24, 365]), [2, 1, 3]);
    

    This should result in 3-D 24x10x365 matrix, from which rows 7 to 18 can be extracted.

  2. The next step is to apply range and transform the result back into a 2-D 365x10 matrix:

    result = permute(range(A(7:18, :, :)), [3, 2, 1]);
    

Therefore, the full solution is:

A = permute(reshape(dat2', [10, 24, 365]), [2, 1, 3]);
result = permute(range(A(7:18, :, :)), [3, 2, 1]);

EDIT:
To make the solution even more generic, you can use DateV to obtain the indices of the desired rows:

idx = DateV(1:24, 4) >= 6 & DateV(1:24, 4) < 18;

and then use it in the solution like so:

A = permute(reshape(dat2', [10, 24, 365]), [2, 1, 3]);
result = permute(range(A(idx, :, :)), [3, 2, 1]);

Upvotes: 2

Related Questions