MATLAB Answers

Efficient way of reading cell arrays

7 views (last 30 days)
djr
djr on 4 Aug 2014
Edited: per isakson on 4 Dec 2016
Hi
What would be the most efficient way to read content from cells; is it using for loops or cellfun functions. For example, My data have 3 layers of cells (cell in cell in cell). So, I used 3 'for loops' to get to data that are in the third cell. The code looks like this:
for j=1:size(evaldata,1)
for k=1:size(evaldata{j,1},1)
for l=1:size(evaldata{j,1}{k,2},1)
A{l,:}={evaldata{j,1}{k,1},(sscanf(evaldata{j,1}{k,2}{l,1}, '%f').')};
%
if ismember(A{l,1}{1,2}(2),v)
store{j}{l,k}{1,1}=A{l}{1,1};
for w=2:14
store{j}{l,k}(1,w)={A{l}{1,2}(w-1)};
end
else
store{j}{l,k}='not selected';
end
end
end
fz=cellfun(@isempty,evaldata{1,1});
fzz=find(fz(:,2));
for kk=1:size(fzz,1)
store{j}{1,fzz(kk)}=evaldata{1,1}{fzz(kk),1};
end
end
It probably does not mean much without explaining what it does... However, this looks like a brute force. Is there a bettwer way to deal with multiple array cells that are not the same size or declaration (strings, numbers, ...)?
Last few days I asked for help several times. This time I decided to do it by muself and I ended up having 100 loops :( :( :(. Maybe because I only used Fortran when it comes to programing.
Cheers, Djordje

  3 Comments

Image Analyst
Image Analyst on 4 Aug 2014
I only see 5 loops. Does it even work? If it does, then time it with tic and toc, and compare to the cellfun way. I'm not sure how you can even keep track of things. A cell within a cell within a cell? Wow. Can't you just use regular numerical arrays?
djr
djr on 5 Aug 2014
I need 20 min just to catch how all these loops are running and how they are connected to each other. I'll try tomorrow to solve it in a more sufficient way.
And yes... it does work. Somehow. :D
Image Analyst
Image Analyst on 5 Aug 2014
Well you're right that it doesn't mean much without any explanation. No comments at all , and it looks so cryptic that I didn't even attempt to figure out what it does. It looks like you're trying to transfer some data from A and evaldata into store, but that's about all I got from it.

Sign in to comment.

Accepted Answer

per isakson
per isakson on 5 Aug 2014
Edited: per isakson on 4 Dec 2016
I continue where we left in your last question. I assume
  • There are many data-files in one folder
  • The names of the data-files match '\d[4}_\d{4}', i.e four digits, underscore followed by four digits. It's hard-coded.
The function, add_met_data_to_lib, can be used repeatedly to read data-files in many folders. Syntax
Create new lib
lib = add_met_data_to_lib('h:\m\cssm\*_*.txt')
add to existing lib
lib = add_met_data_to_lib('h:\m\cssm\*_*.txt', lib )
Example:
>> lib = add_met_data_to_lib('h:\m\cssm\*_*.txt')
lib =
Map with properties:
Count: 2925
KeyType: char
ValueType: any
>> lib('19491020T0600')
ans =
1.0e+03 *
Columns 1 through 9
0.0010 0.0110 0.0804 0.0526 1.0232 -0.0001 0.0026 0.0058 0.4113
0.0020 0.0010 0.0726 0.0449 1.0288 -0.0003 0.0050 0.0057 0.9271
0.0030 0 0.0393 0.0497 1.0288 -0.0004 0.0100 0.0105 0.1410
Columns 10 through 13
0.0020 0.0008 0.0790 0.0537
0.0004 0.0001 0.0747 0.0450
0.0018 0.0005 0.0360 0.0524
>>
where
function lib = add_met_data_to_lib( glob, lib )
narginchk( 1, 2 )
if nargin == 1
lib = containers.Map('KeyType','char','ValueType','any');
end
%
file_list = transpose( dir( glob ) );
%
is_met_file = not( isempty( regexp( [file_list.name] ...
, '\d{4}_\d{4}', 'start' ) ) );
file_list( not( is_met_file ) ) = [];
%
for file = file_list
lib = met2lib( file.name, lib );
end
end

  23 Comments

djr
djr on 6 Aug 2014
I think I found the format of ftm that created the output:
write (fmt,'(''(i3,1x,i2,'',i1,''(2f8.2),f8.2,'',i1, * ''f8.3,20(1pe10.3.1))'')')
djr
djr on 6 Aug 2014
Hi,
I made a template for output file (attached). The output is for anticyclone case and therefore there is 'a' at the and of each variable name. I used the same names for variables as they appear in the dateset (i.e. tracking scheme output).
I used the following command to create the output file:
T = table (datetime, ioa, fa, ca, dpa, rda, Vsa, dist_pa, dist_va)
writetable(T, 'acyc_output.txt', 'Delimiter', '\t', 'WriteRowNames',true)
Few notes:
  • dist_pa would be a distance from the pressure center to weather station (first pair of coordinates (columns 3 and 4))
  • dist_va would be a distance from the vorticity center to weather station (columns 12 and 13)
  • I don't need first column (named 'k' in the database)
  • I don't need 9th column (named 'zs' in the datebase)
  • And I don't need lat and log, but instead distances (dist_pa and dist_va) that will be calculated based on the lat/lon data.
Hopefully this helped.
P.S.
My e-mail is dj**************om
per isakson
per isakson on 7 Aug 2014
Yes, this becoming too specific for this forum. I sent a mail and blurred your mail-address

Sign in to comment.

More Answers (1)

Ahmet Cecen
Ahmet Cecen on 5 Aug 2014
This really doesn't make much sense without context to me. This is an incredibly inefficient data storage configuration. From what I understand, you can access everything you need in 3 for loops. (for the first eval.mat)
for i=1:14
currentI=eval{i}
for j=1:size(currentI,1)
header1=currentI{j,1};
currentJ=currentI{j,2};
for k=1:size(currentJ,1}
currentdata=currentJ{k,1}
PUT YOUR EVALUATION FUNCTION HERE
end
end
end
With this, at the evaluation step you have the following information: '0101194900' 1 0 77.20 43.17 1038.47 -0.268 7.442 7.1651644.929 0.000 0.000 75.96 41.45

  0 Comments

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by