MATLAB Cut 3D array of daily data into monthly segments - matlab

I have a 1437x159x1253 large matrix (let's call it A) of daily sea ice data for a little over 2 years. I need to write a code that takes the daily data from each month and does mean(A, 3) on it. So basically, 1253 is the t in days. If I start from January, I need to do mean(A,3) of the first 31 days, then the mean(A,3) of February, the next 28 or 29 days. Because the days alternate between 31 and 30 (and 28 or 29 for February), I don't know how to write a code to do this. I can do it manually, but that would take a while.
Thanks!

You can initialize an array containing the number of days in each month, Mon = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] using boolean to check whether it's a leap year (to set Mon(2) = 29). The number of days will help you index each month appropriately, using a loop like:
index=1;
for i=1:12
average = mean(A(:,:,index:(index+Mon(i)-1),3);
index = index+M(i); % Starting location of the next month
end

Related

Chosing specific dates/hours from an array

I have a matrix that has 3months of data or so..Its a 952x1 matrix with the elements in the following format(3 hourly )
Aug-05-2015 03:00:00
Aug-05-2015 06:00:00
Aug-05-2015 09:00:00
Aug-05-2015 12:00:00
Aug-05-2015 15:00:00
Aug-05-2015 18:00:00
Aug-05-2015 21:00:00
Aug-06-2015 00:00:00
Aug-06-2015 03:00:00
Aug-06-2015 06:00:00
I would want to choose say only day timings/ only night or say for august month alone. How do i do that.
Further to my question, if I have a group of .wav files and Im trying to pick only month wise or do daily psd averages etc or chose files belonging to a month how to go about? The following are first 10 .wav files in a .txt file that are read into matlab code-
AMAR168.1.20150823T200235Z.wav
AMAR168.1.20150823T201040Z.wav
AMAR168.1.20150823T201845Z.wav
AMAR168.1.20150823T202650Z.wav
AMAR168.1.20150823T203455Z.wav
AMAR168.1.20150823T204300Z.wav
AMAR168.1.20150823T205105Z.wav
AMAR168.1.20150823T205910Z.wav
AMAR168.1.20150823T210715Z.wav
yyyymmddTHHMMSSZ.wav is part of the format to get sense of some parameters.
Thanks.
Are these datetimes? If so, you can use logical indexing here if you make use of some of the datetime functions. To get the times in August:
t = datetime(2015, 8, 1, 3, 0, 0) + hours(3:3:3000)';
t(month(t) == 8) % Times in August
To get the times that are during the day or night:
t(hour(t) < 12) % Day times
t(hour(t) >= 12) % Night times

Unix Time stamp day of the week pattern

If all I have is the unix timestamp and I am not able to use any functions to format it (such as day of the week or date) is there any known pattern by looking at the timestamp to deduce what day of the week it is?
for example perhaps all timestamps that are divisible by 150 are Mondays
The Unix Epoch (Jan 1, 1970, 00:00) was on a Thursday. Specifically it marked the beginning of a Thursday.
The first Monday after the Unix Epoch begins on Jan 5, 1970, 00:00. This is a UNIX timestamp of 96 hours.
The second Monday after the Unix Epoch begins on Jan 12, 1970, 00:00. This is a UNIX timestamp of 264 hours.
Let's assume X is your Unix timestamp in hours. The formula ((X - 96) % (264 - 96)) / 24 will return a zero-based weekday index where 0 is Monday and 6 is Sunday. The formula looks like this:
(X - 96) % 168 / 24 (if X is your timestamp in hours)
(X - 345600) % 604800 / 86400 (if X is your timestamp in seconds)
(X - 345600000) % 604800000 / 86400000 (if X is your timestamp in milliseconds)
If i experiment with exactly this moment, defined by a Unix timestamp of 1466710873523 ms i would get (1466710873523 - 345600000) % 604800000 / 86400000 which is ~3.8 (meaning it's Thursday) (almost Friday though :). Note though that it's Thursday UTC - in certain timezones it might be different so for local time you would need to take timezone offset into account.
From my own observations, the timestamp at midnight GMT ends in 000 every 6 days. The sequence is as follows: 000, 400, 800, 200, 600, 000, 400, 800, 200...
So, today (in UCT) started at 1465948800 and has been Wednesday.
So I know that that tomorrow's starting timestamp will end with 200 etc.
If you count the days from today (1465948800) to your desired date and divide by 6,
if the remainder is 1, the ending will be '200',
2: '600',
3: '000',
4: '400',
5: '800'.
Because a week has 7 days, if this Wednesday ended in 800, next Wednesday will end in 200 and the following wednesday in 600, etc.

How to detect 4 digit using regexp

How do I get the year (4 digits) when given a source code, I can only detect the day (29), but could not detect the year(1997). There is something wrong in my regexp checking.
age = regexp(CharData,'(\d{1,4})','match','once')
For example,
Registered On
March 29, 1997
Desired output: 1997
Error output: 29
for i = 1:2
data2=fopen(strcat('DATA\PRE-PROCESS_DATA\F22_TR\f22_TR_pdata_',int2str(i),''),'r')
CharData = fread(data2, '*char'); %read text file and store data in CharData
fclose(data2);
age = regexp(CharData,'(\d{4})','match','once')
end
file : f22_TR_pdata_1 --> Registered On
June 24, 1997
file : f22_TR_pdata_2 --> Registered On
March 29, 1997
Age: 1997
To only grab four digits
age = regexp(CharData,'(\d{4})','match','once')
Doing d{1,4} means look for numbers with a length between 1 and 4. Meaning, 1, 29, 123, 4444 would all match because their length is between 1 and 4
d{4} says, get me the number with exact length of 4. Meaning, 1997, 2001, 1800 would all match.

How to read files using for loop in Matlab?

I need to read 8760 files (365 days * 24 hours = 8760) of small size (60 kb) and aggregate values and take average of some values.
Earlier, I have used the below stated code for reading *.csv files:
for a=1:365
for b=1:24
s1=int2str(a);
s2=int2str(b);
s3=strcat('temperature_humidity',s1,'_'s2);
data = load(s3);
% Code for aggregation, etc
end
end
I was able to run this code. However now the file name is little different and I am not sure how to read these files.
Files are named like this:
2005_M01_D01_0000(UTC-0800)_L00_NOX_1HR_CONC.DAT
where M = Month, so the values are 01, 01, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12;
D = Day, so the values are 01, 02, 03, ..., 31;
Hours is in this format: 0000, 0100, 0200, ..., 1800, ..., 2300.
Please take a look at the attached image for file name . I need to read these files. Please help me.
Thank you very much.
I would use dir:
files=dir('*.dat')
Or you can construct the filenames with
name = sprintf('%d_M%2d etc.',...)

How can I convert a 5 digit int date and 7 digit int time to a real date?

I've come across some data where the date for today's value is 77026 and the time (as of a few minutes ago) is 4766011. FYI: today is Fri, 18 Nov 2011 12:54:46 -0600
I can't figure out how these represent a date/time, and there is no supporting documentation.
How can I convert these numbers to a date value?
Some other dates from today are:
77026 | 4765509
77026 | 4765003
77026 | 4714129
77026 | 4617107
And some dates from what is probably yesterday:
77025 | 6292509
77025 | 6238790
77025 | 4009544
Ok, with your expanded examples, it would appear the first number is a day count. That'd put this time system's epoch at
to_days(today) = 734824
734824 - 77025 = 657799
from_days(657799) = Dec 29, 1800
The time values are problematic, it looks like they're decreasing (unless you listed most recent first?), but if they are some "# of intervals since midnight", then centi-seconds could be likely. That'd give us a range of 0 - 8,640,000.
4765509 = 47655.09 seconds -> sec_to_time(47655) = 13:14:15
sec_to_time(47650.03) -> 13:14:10
sec_to_time(47141.29) -> 13:05:41
sec_to_time(46171.07) -> 12:49:31