How to re-organize cell arrays assigning more values to the same index
2 views (last 30 days)
Show older comments
Giovanni Rinaldi
on 2 Aug 2016
Answered: Giovanni Rinaldi
on 4 Aug 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!
3 Comments
Accepted Answer
More Answers (1)
Guillaume
on 3 Aug 2016
Edited: Guillaume
on 3 Aug 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 Comments
Guillaume
on 3 Aug 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
See Also
Categories
Find more on Logical in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!