问题
I have a simple question but I can't figure it out or find it anywhere. I have a cell array where c{1} is a vector and c{2} is a vector but of different lengths, up to c{i}. What I want is one vector that is [c{1};c{2};c{3}...c{i}]. What is the most efficient way to do this?
回答1:
The following one-liner even works for completely inconsistent inputs:
result = [cell2mat(cellfun(@(x) x(:), A, 'uni', 0)')]'
Example:
for:
A{1} = [1, 2, 3, 4, 5];
A{2} = [6; 7; 8; 9];
A{3} = [10, 12; 11, 13];
it returns:
result =
1 2 3 4 5 6 7 8 9 10 11 12 13
回答2:
Matlab/Octave allows this king of really-not-efficient but very-convenient notation, assuming a
is a structure only containing column-vectors:
x = []; #% A fresh new vector/matrix/tensor, who knows?
for i=1:numel(a) #% parse container item by item
x = [x;a{i}]; #% append container item a{i} to x in a column-fashion way
end
This will works but it is bloody inefficient since it will reallocate x
each for
step and it is not bulletproof (no error handling, no type checking): therefore it will fail if it encounters anything (matrix, string, row vector) but column vector which are likely to be found in such containers.
Anyway, it will ease a not-so-stringent-and-heuristic design, but please consider reimplementing when robust design is needed.
回答3:
You can padding each cell with zeros, and align the lengths to the longest cell vector. It is done in a loop by iterating each cell vector.
回答4:
This depends on whether the vectors in c are row or column vectors. But usually the fastest and most compact ways are:
c={[1 2 3], [4 5 6 7 8], [9 10]}
cell2mat(c)
cat(2, c{:})
or
c={[1 2 3]', [4 5 6 7 8]', [9 10]'}
% cell2mat(c) % Doesn't work.
cat(1, c{:})
so personally, I prefer cat.
回答5:
In Matlab; without loops:
If the cell array contains column vectors and you want to arrange them into one big column vector:
result = vertcat(c{:}); %// vertically concat all vectors
Example:
>> c = {[1;2], [1;2;3]}; >> result = vertcat(c{:}) result = 1 2 1 2 3
If the cell array contains row vectors, you can arrange them as rows of a matrix, filling non-existent values with
NaN
(or any other value):M = max(cellfun(@numel, c)); %// max length of vectors c2 = cellfun(@(row)[row NaN(1,M-numel(row))], c, 'uni', 0); %// fill with NaN result = vertcat(c2{:}); %// concat all equal-size row vectors into a matrix
Example:
>> c = {[1 2], [1 2 3]}; >> M = max(cellfun(@numel, c)); >> c2 = cellfun(@(row)[row NaN(1,M-numel(row))], c, 'uni', 0); >> result = vertcat(c2{:}) result = 1 2 NaN 1 2 3
来源:https://stackoverflow.com/questions/20891219/matlab-octave-extracting-elements-from-different-sized-vectors-in-a-cell-array