Make array with elements repeating as many times as specified in another list.

6 visualizzazioni (ultimi 30 giorni)
I have a cell array of vectors, where each vector is of a different length. Something like (but much larger):
a{1} = [1, 2, 4];
a{2} = [5, 3, 8, 9];
a{3} = [2, 6, 3, 7, 8, 1];
I want to create a new array where 1s are repeated as many times as length of a{1}, 2s are repeated as many times as length of a{2} and so on.
I am currently using a loop to do this as:
% Vector of sequence of 1s, 2s etc.
y_val = [];
for k = 1: length(a)
y_val = [y_val, k * ones(1, length(a{k}))];
end
Is there a faster way of doing this?
The actual variables in my code are much larger. Thus, I want the fastest way of solving this.
(I have access to all the toolboxes in matlab)
Note: I also have access to a vector a_lengths, in which a_lengths(i) is the length of a{i}.
  1 Commento
atharva aalok
atharva aalok il 14 Ago 2023
Modificato: atharva aalok il 14 Ago 2023
% Allocate cell array
cell_array_length = 2000;
a_lengths = randi([5000, 10000], 1, cell_array_length);
for i = 1: cell_array_length
a{i} = rand(1, a_lengths(i));
end
% My code
tic
% Vector of sequence of 1s, 2s etc.
y_val_my = [];
for k = 1: length(a)
y_val_my = [y_val_my, k * ones(1, length(a{k}))];
end
toc
Elapsed time is 53.341348 seconds.
% My Other code
tic
y_val_myother = zeros(1, sum(a_lengths));
idx_list = [0, cumsum(a_lengths)];
for k = 1: length(a)
y_val_myother(idx_list(k)+1: idx_list(k+1)) = k;
end
toc
Elapsed time is 0.053105 seconds.
% Bruno's Code
tic
y_val_bruno = repelem(1:length(a), cellfun('length', a));
toc
Elapsed time is 0.023451 seconds.
% Chetan's Code
tic
cell_lengths = cellfun(@length, a);
y_val = arrayfun(@(k) k * ones(1, cell_lengths(k)), 1:length(a), 'UniformOutput', false);
y_val_chetan = [y_val{:}]; % Convert from cell to array
toc
Elapsed time is 0.104331 seconds.
% Walter (Bruno's code + known lengths of vectors)
tic
y_val_walter = repelem(1:length(a), a_lengths);
toc
Elapsed time is 0.023355 seconds.
% disp(y_val_my);
% disp(y_val_myother);
% disp(y_val_bruno);
% disp(y_val_chetan);
% disp(y_val_walter);

Accedi per commentare.

Risposta accettata

Walter Roberson
Walter Roberson il 14 Ago 2023
y_val = repelem(1:length(a_lengths), a_lengths);

Più risposte (2)

Bruno Luong
Bruno Luong il 14 Ago 2023
a{1} = [1, 2, 4];
a{2} = [5, 3, 8, 9];
a{3} = [2, 6, 3, 7, 8, 1];
y_val = repelem(1:length(a), cellfun('length', a))
y_val = 1×13
1 1 1 2 2 2 2 3 3 3 3 3 3

C B
C B il 14 Ago 2023
Modificato: C B il 14 Ago 2023
a{1} = [1, 2, 4];
a{2} = [5, 3, 8, 9];
a{3} = [2, 6, 3, 7, 8, 1];
tic
% Vector of sequence of 1s, 2s etc.
y_val = [];
for k = 1: length(a)
y_val = [y_val, k * ones(1, length(a{k}))];
end
disp(y_val)
1 1 1 2 2 2 2 3 3 3 3 3 3
toc
Elapsed time is 0.033261 seconds.
tic
cell_lengths = cellfun(@length, a);
y_val = arrayfun(@(k) k * ones(1, cell_lengths(k)), 1:length(a), 'UniformOutput', false);
y_val = [y_val{:}]; % Convert from cell to array
disp(y_val)
1 1 1 2 2 2 2 3 3 3 3 3 3
toc
Elapsed time is 0.007679 seconds.

Categorie

Scopri di più su Programming in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by