2

I have a cell array that is of size approximately 900k x 1 which contains dates in the format '5/13/2015 23:53'. I'm trying to create an integer array of the same length that contains just the hour in each date cell. What's the fastest/best way to do this?

Edit I only have access to the following toolboxes:

MATLAB                                                Version 8.6         (R2015b)
Simulink                                              Version 8.6         (R2015b)
Control System Toolbox                                Version 9.10        (R2015b)
DSP System Toolbox                                    Version 9.1         (R2015b)
Image Processing Toolbox                              Version 9.3         (R2015b)
Instrument Control Toolbox                            Version 3.8         (R2015b)
Optimization Toolbox                                  Version 7.3         (R2015b)
Signal Processing Toolbox                             Version 7.1         (R2015b)
Simulink Control Design                               Version 4.2.1       (R2015b)
Statistics and Machine Learning Toolbox               Version 10.1        (R2015b)
Symbolic Math Toolbox                                 Version 6.3         (R2015b)

Edit2:

tic
datesmat = datevec(Dates);
hours = datesmat(:,4);
toc

tic
Hours = cell2mat(cellfun(@(x) str2double(x(end-4:end-3)), Dates, 'UniformOutput', false));
toc

Elapsed time is 90.233473 seconds.
Elapsed time is 14.168023 seconds.
1
  • 1
    I stand flabbergasted and corrected. It's a weird world, where cellfun is actually the fastest. Do note that for accurate timing one'd better use timeit, which is specially designed for this; not that it matters with such a great difference. Commented Mar 22, 2017 at 22:10

3 Answers 3

3

You can use hour method.

Example:

Hour = hour({'5/13/2015 21:53', '5/13/2015 23:53'})

Result:

Hours =

    21    23

Example without financial toolbox:

Dates = {'5/13/2015 21:53', '5/13/2015 23:53'};

Hours = cell2mat(cellfun(@(x) str2double(x(end-4:end-3)), Dates, 'UniformOutput', false));
Sign up to request clarification or add additional context in comments.

Comments

3
date = {'5/13/2015 23:53';'5/13/2015 23:53'};
[~,~,~,hours,~,~] = datevec(date); % Extract only the hours

If you don't have the Finance toolbox, you can use a datevec for each date, whose fourth element will be the hour.

(I suspect the hour method of the Finance toolbox does something like this.)

1 Comment

@Rotem Not necessarily; datevec returns an n-by-6 matrix, of which you need only a single column. So the entire operation is just pushing a load of pointless overhead, whereas your cellfun solution only extracts the necessary elements. It's thus using a lot less RAM as well I think, which might come in handy with matrices that big. As well as datevec doing lots of checking and formatting output under the hood; 20 lines do what you want, the other 400 are for all kinds of exceptions. Checking makes it slow as well.
0

A vectorized solution using logical indexing:

B = char(Dates).';
f = B ==':';
x=circshift(f,-1)|circshift(f,-2);
result = str2double(reshape(B(x),2,[]).');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.