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

1 次查看(过去 30 天)
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 个评论
atharva aalok
atharva aalok 2023-8-14
编辑:atharva aalok 2023-8-14
% 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);

请先登录,再进行评论。

采纳的回答

Walter Roberson
Walter Roberson 2023-8-14
y_val = repelem(1:length(a_lengths), a_lengths);

更多回答(2 个)

Bruno Luong
Bruno Luong 2023-8-14
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 2023-8-14
编辑:C B 2023-8-14
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.

类别

Help CenterFile Exchange 中查找有关 Matrices and Arrays 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by