I have a CSV file contains data of Hurricane location coordinates.
I'm new to Matlab so I'm not sure how to treat correctly date and hour cells, especially when they are displayed unconventionally.
I need to apply linear interpolation so I can get the date for every 30 minutes.
Let's assume you read the data in as numerical values
Now you have some matrix like so:
data = [20130928 0 21.1 50.0
20130928 600 22.2 50.3
20130928 1200 23.3 50.6
20130928 1800 24.2 50.6];
To convert the first two columns to datetime values, we could do this:
% Concatenate first two columns, including making all times 4 digits by 0 padding
fulltime = [num2str(data(:,1)), num2str(data(:,2), '%.4u')]
% Use datetime to convert (cell) times to dates with given format
dates = datetime(cellstr(fulltime),'inputformat', 'yyyyMMddHHmm');
>> dates = 28-Sep-2013 00:00:00
28-Sep-2013 06:00:00
28-Sep-2013 12:00:00
28-Sep-2013 18:00:00
Now we can easily interpolate. First create an array of times we want to use:
% Data value every 30 mins
interpdates = dates(1):hours(0.5):dates(end)
Then use interp1
interpolateddata = interp1(dates, data(:,3:4), interpdates);
>> interpolateddata = 21.1000 50.0000
21.1917 50.0250
21.2833 50.0500
21.3750 50.0750
...
24.1250 50.6000
24.2000 50.6000
Related
I work with csv and must subtract 2 cells with the following date format dd.MM.yyyy HH:mm:ss. I need to extract only the seconds.
Timestamp is a column and I attempted:
data1 = Timestamp(1) ;
data2 = Timstamp(2) ; % returns error
class(data1); % returns cell
data1 - data2 % returns error
How can I convert the cells into a number which I can subtract?
You can index into your cell to extract the date string. Then you can use datenum to convert it to "decimal days since 1st January 0000". Then it's a simple matter of subtracting your starting date (convert that using datenum as well) and changing from decimal days to seconds:
tmp = your_cell{1}; % e.g. 26.11.2020 00:00:00, is a string
tmp_date = datenum(tmp); % MATLAB datenum, decimal days.
tmp_date2 = datenum(your_cell{2});
no_start = tmp_date2-tmp_date; % remove starting date
time_sec = no_start*(24*60*60); % change decimal days to seconds
Or as a oneliner:
(datenum(your_cell{2})-datenum(your_cell{1}))*(24*60*60)
I am running into the following problem in Matlab 2019a.
>> datestr(datetime('20190927','InputFormat','yyyyMMdd')-datetime('20190923','InputFormat','yyyyMMdd'),'yyyymmdd')
ans =
'00000104'
Why is the answer 1 month 4 days? Shouldn't it be zero month 4 days?
EDIT:
I realize that arithmetic on datetime arrays create duration arrays. But I don't know how to set format of duration arrays after doing arithmetic on datetime arrays or how to retrieve the duration data in a format free way.
Datetime arithmetic is what I need. So I am asking the question so I can do datetime arithmetic without issue.
d = datetime('20190927','InputFormat','yyyyMMdd')-datetime('20190923','InputFormat','yyyyMMdd')
returns:
d =
duration
96:00:00
That is, 96 hours. Converting this to a date string results in January 4th. If you start counting hours from midnight on the year 0, 96 hours later you end up on January 4th. There's no 0th month.
What you can do is this:
d = duration(d,'Format','dd:hh:mm:ss')
which returns:
d =
duration
04:00:00:00
You can also do:
d = days(d)
which returns:
d =
4
Let
x=7.369030000162731e+05
x is a matlab date and it is equal to
27.07.2017 00:00:01.406
I want to remove the milliseconds from it (ie. .406)
To do this I convert it to datestr with 'dd.mm.yyyy HH:MM:SS' format
and then again to datenum
datenum(datestr(x,'dd.mm.yyyy HH:MM:SS'))
Is there a simpler way to do this.
If you want the manual approach:
y = floor(x*86400)/86400;
because serial date numbers are measured in days, and 86400 is the number of seconds in a day.
Here's a somewhat simpler way that converts x to a date vector, floors all the elements (which only affects the seconds value in index 6), then converts it back to a serial date number:
x = datenum(floor(datevec(x)));
I have a time series xlsx data which has columns like the following one. I would like to get the row data that are in between 8:00:00 AM to 10:00:00 AM for my analysis. Can any one help me out?
Add Velocity Time
0.128835374 10.34912454 8:44:23 AM
0.20423977 8.078739988 8:47:01 AM
0.110629502 13.4081172 9:19:46 AM
0.088979639 5.057336749 9:24:02 AM
0.128835374 10.60785265 10:21:29 AM
0.20423977 9.46599837 10:23:06 AM
[num, txt] = xlsread('Consective_result.xlsx');
T = num(:,3);
TimeVector = datevec(T)
You almost have it right. Use the third column of your txt cell array, and skip over the first row so you don't get the time header. I'm going to assume that your times are entered in as text. Once you do this, just use datenum and determine those times that are later than 8:00 AM and less than 10:00 AM. datenum can conveniently take in a cell array of strings, and it will output a numeric vector where each time string in your cell array is converted into its corresponding numerical representation.
Once you find those rows, you can filter out the rows in each of num and txt using what we just talked about before you continue. Therefore:
[num, txt] = xlsread('Consective_result.xlsx');
times = txt(2:end,3); %// Get the 3rd column, skip 1st row
time_nums = datenum(times); %// Get the numerical representation of the times
%// Figure out those rows that are between 8:00 AM and 10:00 AM
times_to_choose = time_nums >= datenum('08:00:00AM') & time_nums <= datenum('10:00:00AM');
%// Remove those rows then continue
num(1 + times_to_choose) = [];
txt(1 + times_to_choose) = [];
Take special care that I added a 1 to the indices because we omitted the time header in your spreadsheet. Now, num and txt should only contain those times that are between 8:00 AM and 10:00 AM.
My data (cell) in Matlab looks like this:
00.00.00.515
00.00.00.671
00.00.00.828
00.00.00.984
00.00.01.140
etc.
This is the time stamp: HH:MM:SS:TTT, the T stands for thousandth (=milliseconds). The milliseconds are important because the step size is small. How to convert this data (cell) to data Matlab can handle (double)?
So the data will be as follow:
0.515
0.671
0.828
0.984
1.140
etc.
The minutes and hours should be converted to seconds so it is easy to calculate the total time of the data or the average stepsize. So:
01.30.00.000
will be:
5400.000
seconds
Thanks!
Assuming your cell array contains strings:
ts = {'00.00.00.515'
'00.00.00.671'
'00.00.00.828'
'00.00.00.984'
'00.00.01.140'};
it can be done as follows:
>> cell2mat(cellfun(#(c) sscanf(c,'%d.%d.%f').', ts, 'uniformout', 0)) * [3600 60 1].'
ans =
0.5150
0.6710
0.8280
0.9840
1.1400
This uses cellfun to convert each cell into a row vector of numbers with sscanf,; then concatenates all those vectos into a matrix with cell2mat; and fianlly applies matrix multiplication to compute time.
The code also works if the number of digits is not fixed. For example:
>> ts = {'0.1.00.51'};
>> cell2mat(cellfun(#(c) sscanf(c,'%d.%d.%f').', ts, 'uniformout', 0)) * [3600 60 1].'
ans =
60.5100