How to re-organize cell arrays assigning more values to the same index
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Giovanni Rinaldi
le 2 Août 2016
Réponse apportée : Giovanni Rinaldi
le 4 Août 2016
Hi, I have the following code to assign a certain value to a certain timestep:
starts = [17;249;17]; % starting points for the timesteps
ends = [25;257;25]; % endingpoints for the timesteps
values = [1; 2; 3]; % values to assign in correspondent starts and ends
time_cell = cell (length(starts),1);
values_cell = cell (length(starts),1);
values_repeated = cell (1,length(starts));
for i= 1:length(starts)
time_cell{i,1}= (starts(i,1):1:ends(i,1))';
values_cell{i,1}= values(i);
values_repeated{:,i} = repmat(values_cell(i,1),length(time_cell {i,1}),1);
end
all_times_numeric = cell2mat(time_cell(:,1));
wrong_result = cat(1,values_repeated{:,:});
wrong_result =
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
and would like to organise my array in such a way that for the same value of time, the correspondent cell contains more values in it. In other words, I would like to assign more values to the same timestep. To explain it, in the above example the matrix I would like to obtain is:
right_result =
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
Hope this is clear. Many thanks for your help!
Réponse acceptée
Plus de réponses (1)
Guillaume
le 3 Août 2016
Modifié(e) : Guillaume
le 3 Août 2016
Two notes first:
I find it much clearer to use linear (1D) indexing instead of subscript indexing when dealing with row or column vectors. In particular, I find that writing values_repeated{:,i} when the : means just one row is misleading and begs the question, is this a bug or was it intended. values_repeated{1, i} or better values_repeated{i} would achieve the same.
I recommend using numel instead of length. length is ambiguous when applied to matrices and will break your code.
Now, to answer your question. You would normally use unique to find repeated elements in an array. Unfortunately, unique does not work with cell arrays of numbers (only cell arrays of strings), so we have to be more clever. This is how I would do it:
starts = [17;249;17]; % starting points for the timesteps
ends = [25;257;25]; % endingpoints for the timesteps
values = [1; 2; 3]; % values to assign in correspondent starts and ends
time_cell = arrayfun(@(s, e) (s:e).', starts, ends, 'UniformOutput', false); %a cleaner way of generating time_cell
values_cell = num2cell(values); %a cleaner way of generating values_cell
[tcrow, tccol] = ndgrid(1:numel(time_cell)); %generating indices for cross-comparison of time_cells
issame = arrayfun(@(r, c) isequal(time_cell(r), time_cell(c)), tcrow, tccol); %compare all cells with each other. A 1 indicates identical. Obviously, all 1 on diagonal
merged_values = arrayfun(@(row) values(issame(row, :)).', 1:numel(values), 'UniformOutput', false)'
To generate your final output, one possible way of doing it:
merged_times = vertcat(time_cell{:});
cell_source = repelem(1:numel(time_cell), cellfun(@numel, time_cell))';
[~, origin] = unique(merged_times, 'stable');
right_result = merged_values(cell_source(origin))
Note that if all you wanted is to repeat my merged_values by the number of elements in each time_cell cell (which would make more sense to me than your right_result):
other_result = repelem(merged_values, cellfun(@numel, time_cell))
2 commentaires
Guillaume
le 3 Août 2016
It's always a good idea to mention it in the question if you're not using the latest version of matlab.
You could replicate the way I use repelem with:
function repdvector = my_repelem(vector, repetitions)
%note: does not replicate general repelem behaviour. Just the one in this case
repdvector = cell2mat(arrayfun(@(e, r) repmat(e, 1, r), vector(:), repetitions(:), 'UniformOutput', false)); %force both vectors to column with : to ensure they're the same shape
if iscolumn(vector)
repdvector = repdvector(:);
end
end
Voir également
Catégories
En savoir plus sur Logical dans Help Center et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!