Vectorising nested for loops
1 view (last 30 days)
Show older comments
Hi,
I’m trying to vectorise the following code snippet that works using the attached data. Unfortunately, I couldn’t succeed. Any ideas on how to deal with it?
Cheers,
Mel
k=0;
struct_data = struct('idx',[],'count',[],'size',[]);
for i = 1:size(table_data,1)
for j = 1:list(i)
k=k+1;
struct_data(k,1).idx = k;
struct_data(k,1).count = table_data.count(i);
struct_data(k,1).size = table_data.size(i);
end
end
2 Comments
Stephen23
on 10 Mar 2023
Are you intentionally storing lots of scalar cell arrays containing character vectors, or is the intent to actually just store the character vectors without the superfluous scalar cell arrays? If you only need the text, replace
table_data.size(i);
with
table_data.size{i};
Accepted Answer
Voss
on 10 Mar 2023
Edited: Voss
on 10 Mar 2023
% unzip and load data
unzip data.zip
load data.mat
% run the loop method, for later comparison
k=0;
struct_data = struct('idx',[],'count',[],'size',[]);
for i = 1:size(table_data,1)
for j = 1:list(i)
k=k+1;
struct_data(k,1).idx = k;
struct_data(k,1).count = table_data.count(i);
struct_data(k,1).size = table_data.size{i}; % note this change:
% I made struct_data(k).size a char, instead of
% a scalar cell array containing a char
end
end
struct_data_save = struct_data;
% a "vectorized" method
idx = find(list);
struct_data = table2struct(removevars(table_data(repelem(idx,list(idx)),:),'district'));
C = num2cell(1:numel(struct_data));
[struct_data.idx] = deal(C{:});
% are the results the same?
isequal(struct_data,struct_data_save)
2 Comments
Voss
on 10 Mar 2023
Edited: Voss
on 10 Mar 2023
If you really want struct_data(k).size to be a 1x1 cell array containing a character vector (as in {'venti'}), as opposed to just a character vector (as in 'venti'), you can do it with a couple of additional lines of code:
% unzip and load data
unzip data.zip
load data.mat
% run the loop method, for later comparison
k=0;
struct_data = struct('idx',[],'count',[],'size',[]);
for i = 1:size(table_data,1)
for j = 1:list(i)
k=k+1;
struct_data(k,1).idx = k;
struct_data(k,1).count = table_data.count(i);
struct_data(k,1).size = table_data.size(i); % scalar cell array this time
end
end
struct_data_save = struct_data;
% a "vectorized" method
idx = find(list);
struct_data = table2struct(removevars(table_data(repelem(idx,list(idx)),:),'district'));
C = num2cell(1:numel(struct_data));
[struct_data.idx] = deal(C{:});
C = num2cell({struct_data.size});
[struct_data.size] = deal(C{:});
% are the results the same?
isequal(struct_data,struct_data_save)
More Answers (1)
Stephen23
on 10 Mar 2023
S = load('data.mat')
list = S.list
tdat = S.table_data
k=0;
out0 = struct('idx',[],'count',[],'size',[]);
for i = 1:size(tdat,1)
for j = 1:list(i)
k=k+1;
out0(k,1).idx = k;
out0(k,1).count = tdat.count(i);
out0(k,1).size = tdat.size{i};
end % ^ ^ fixed indexing
end
out0
Without an explicit loop:
out1 = repelem(table2struct(removevars(tdat,'district')),list);
idx = num2cell(1:numel(out1));
[out1.idx] = idx{:}
isequal(out0,out1)
See Also
Categories
Find more on Startup and Shutdown in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!