please help simplify this for-loop-hell

The code below works as it should, but its slooow. I have a data variable with x number of cells. I want every row in column 6 of each cell, to match up and leave the respectively row value from column 3, in those rows. If the value from column 6 not match between the cells in data, I instead place a zero. I describe the data first:
data = 5; % data: cells with different size of rows e.g. 2000x6, 4000x6, 8000x6.
biggest_data_size = 8000; % can be other size as well (the one cell in data with most rows)
biggest_data_series = % this is 8000x1 series the 6. column in data{biggest_data_idx}. Unique increasing number (the one cell in data with most rows). I want this one as the first column in the result.
data_qty = 5; % can be other size as well, its the number of cells in data
result= [ biggest_data_series zeros(biggest_data_size,data_qty) ];
for i = 1 : data_qty
data_current_size = size(data{i},1);
for j = 1 : biggest_data_size
for h = 1 : data_current_size
if result(j,1) == data{i}(h,6)
result(j,i+1) = data{i}(h,3);
end
end
end
end
Hope I am clear enough. Any suggestions is very appreciated...

4 comentarios

dpb
dpb el 1 de Nov. de 2018
Editada: dpb el 1 de Nov. de 2018
Show a small sample dataset(*) and what you want the result to be...it's much easier to attack the problem itself with an illustration rather than try to figure out a convoluted piece of code.
(*) Arrays of 5 and 7 or 10 elements serve to illustrate just as well as does 2000 and are small enough to visualize and post.
Martin
Martin el 1 de Nov. de 2018
Editada: Martin el 1 de Nov. de 2018
ok I will do that
EDIT: Martins "Answer" moved here and formatted correctly:
data{1} = [ 0 0 1111 0 0 1 ;
0 0 1112 0 0 1.5 ;
0 0 1113 0 0 2 ;
0 0 1114 0 0 2.5 ;
0 0 1115 0 0 3 ]
and
data{2} = [ 0 0 101 0 0 1 ;
0 0 102 0 0 2 ;
0 0 103 0 0 3 ;
0 0 104 0 0 4 ; ]
with the above example I need to reach this (as my stupid today-code)
result = [1 1111 101 ;
1.5 1112 0;
2 1113 102 ;
2.5 1114 0 ;
3 1115 103 ];
E.g. It's match up the first column, and leave the third columns row. If not its just a zero !
Keep in mind I'm only using 2 cells in this example. Data (with cells within can be much larger). Tell me if you need me to provide any other information!
Stephen23
Stephen23 el 1 de Nov. de 2018
@Martin: your example is not clear. You wrote in your question that you want the first column of result to be from "...(the one cell in data with most rows)", but in your example data{2} has the most rows yet you used data{1} for the first column. Please explain how this works.
Martin
Martin el 1 de Nov. de 2018
@Stephen, you are right. I just corrected it

Iniciar sesión para comentar.

 Respuesta aceptada

Bruno Luong
Bruno Luong el 1 de Nov. de 2018
Editada: Bruno Luong el 1 de Nov. de 2018
data = {ceil(20*rand(100,6)) ceil(20*rand(50,6)) ceil(10*rand(20,6))};
biggest_data_series = randperm(15)';
biggest_data_size = length(biggest_data_series)
data_qty = length(data);
result= [ biggest_data_series zeros(biggest_data_size,data_qty) ];
% Your for-loop
for i = 1 : data_qty
data_current_size = size(data{i},1);
for j = 1 : biggest_data_size
for h = 1 : data_current_size
if result(j,1) == data{i}(h,6)
result(j,i+1) = data{i}(h,3);
end
end
end
end
result
% vectorize way
data_qty = length(data);
A = arrayfun(@(i) [i+zeros(size(data{i},1),1), data{i}(:,[6 3])], 1:data_qty, 'unif', 0);
A = cat(1,A{:});
[b,J] = ismember(A(:,2), biggest_data_series);
picklastrowfun = @(r) A(max(r),3);
rs = accumarray([J(b),A(b,1)],find(b),[biggest_data_size,data_qty],picklastrowfun);
rs = [biggest_data_series, rs]

Más respuestas (0)

Categorías

Más información sobre Loops and Conditional Statements en Centro de ayuda y File Exchange.

Productos

Preguntada:

el 31 de Oct. de 2018

Comentada:

el 1 de Nov. de 2018

Community Treasure Hunt

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

Start Hunting!

Translated by