Vectorising nested for loops

1 Ansicht (letzte 30 Tage)
Melanie VT
Melanie VT am 10 Mär. 2023
Verschoben: Stephen23 am 11 Mär. 2023
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 Kommentare
Stephen23
Stephen23 am 10 Mär. 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};
Melanie VT
Melanie VT am 10 Mär. 2023
Thank you for your contribution!

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Voss
Voss am 10 Mär. 2023
Bearbeitet: Voss am 10 Mär. 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)
ans = logical
1
  2 Kommentare
Voss
Voss am 10 Mär. 2023
Bearbeitet: Voss am 10 Mär. 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)
ans = logical
1
Melanie VT
Melanie VT am 10 Mär. 2023
That is awesome! Thank you so much for providing solutions for both scenarios🙏

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Stephen23
Stephen23 am 10 Mär. 2023
S = load('data.mat')
S = struct with fields:
list: [27×1 double] table_data: [27×3 table]
list = S.list
list = 27×1
0 100 60 0 0 0 0 0 0 0
tdat = S.table_data
tdat = 27×3 table
district count size ________ _____ __________ {[ 1]} 91 {'venti' } {[ 2]} 116 {'venti' } {[ 3]} 112 {'venti' } {[ 4]} 8 {'venti' } {[ 5]} 23 {0×0 char} {[ 6]} 16 {0×0 char} {[ 7]} 7 {0×0 char} {[ 8]} 1 {0×0 char} {[ 9]} 28 {0×0 char} {[10]} 58 {'tall' } {[11]} 43 {'venti' } {[12]} 13 {'trenta'} {[13]} 68 {'tall' } {[14]} 108 {'grande'} {[15]} 102 {'venti' } {[16]} 76 {'venti' }
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
out0 = 160×1 struct array with fields:
idx count size
Without an explicit loop:
out1 = repelem(table2struct(removevars(tdat,'district')),list);
idx = num2cell(1:numel(out1));
[out1.idx] = idx{:}
out1 = 160×1 struct array with fields:
count size idx
isequal(out0,out1)
ans = logical
1
  1 Kommentar
Melanie VT
Melanie VT am 10 Mär. 2023
Verschoben: Stephen23 am 11 Mär. 2023
This solution is even almost 1.5 times faster than the one above! I’m truly grateful to you all🙏🏼
This post is also an Accepted Answer with appreciation😊

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Startup and Shutdown finden Sie in Help Center und File Exchange

Produkte


Version

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by