Concatenate cell arrays from structs

22 Ansichten (letzte 30 Tage)
Ioannis Agalliadis
Ioannis Agalliadis am 26 Jul. 2017
I have the following struct named output.
Inside this output I have 27 fields with their values. Their values are 1x8 cell each. Each cell has different number of rows.
I want to:
Concatenate all the cell arrays (struct values) in such a way where the final result will be an array with all 8 columns and the rows of each cell array.
Here is what it looks like:
struct=output
field value
smooth 1x8 cell array
rms 1x8 cell array
stft 1x8 cell array
haar 1x8 cell array
sym 1x8 cell array
. .
. .
. .
. .
Each cell array has different number of rows!
Can I concatenate all the cell arrays into one? If yes, is there any efficient way to do this?
Thank you in advance!
  6 Kommentare
John BG
John BG am 30 Jul. 2017
Bearbeitet: John BG am 30 Jul. 2017
Calimera Ioannis
Guillame and Stephen Cobeldick are very experienced MATLAB forum contributors, the kind that usually with a single shot they get the right answer.
But I'd like to point out the fact that unless you post the structure, or a significant chunk of it, you are keeping them, and all other readers, blind folded: Like in a Mexican pinyata party, guessing where the pinyata is.
So, please would you be so kind to make available the structure, as attachment, as .mat file, the whole structure, or a sample of it.
If containing sensitive data, just make a copy, and edit values with noise.
Regards
John BG
Ioannis Agalliadis
Ioannis Agalliadis am 31 Jul. 2017
I found out how to solve my issue.
This is how it inserts the contents of each matrix of a cell into one final matrix:
for i=1:numel(featureNames)
featureName = featureNames{i};
for j=1:numel(output.(featureName))
matrix(offset+1:offset+obj.dimensions.(featureName),j) = output.(featureName){j};
end
offset = offset + obj.dimensions.(featureName);
end
With the variable offset I keep track of the number of rows of each matrix of each cell and then I concatenate them in a final matrix which dimensions are a large number of rows x with 8 columns. The sad thing is, that this was not the preferred matrix I should create but a different one.

Melden Sie sich an, um zu kommentieren.

Antworten (2)

Guillaume
Guillaume am 26 Jul. 2017
Bearbeitet: Guillaume am 26 Jul. 2017
1x8 cell array means 8 columns and one row. So it looks like your cell arrays have all the same number of rows, exactly one.
Perhaps you mean the contents of the cell arrays, each cell array has 8 something, but you haven't told us anything about what these somethings are (numeric matrices? column vectors maybe? char arrays?).
I'm very unclear on what you want to achieve. If you want to concatenate the cell arrays of all the fields together, then it's easily done:
c = struct2cell(youstructure);
c = vertcat(c{:});
This will create an mx8 cell array, where m is the number of fields. The size of the contents of the cell array have no influence on this.
  3 Kommentare
Guillaume
Guillaume am 26 Jul. 2017
I'm still not clear on your data structure. But first, is the above solution what you're after or not all?
if your cell arrays are 1x8 then it is the cell arrays that have 8 columns (and one row).
This is a 1x8 cell array:
c1 = {[], [], [], [], [], [], [], []}
whose contents is all empty (0x0) double matrices. This is another 1x8 cell array
c2 = arrayfun(@magic, 1:8, 'UniformOutput', false)
whose contents are double matrices of varying sizes (1x1 to 8x8).
So what is the size of the cell arrays, and what is the size and type of the contents of each cell? Probably best, would be for you to upload a mat file with your structure so we can see for ourselves what's what.
Ioannis Agalliadis
Ioannis Agalliadis am 26 Jul. 2017
In the updated question there is an image where you can see the dimensions of the cell arrays I am talking about.

Melden Sie sich an, um zu kommentieren.


Stephen23
Stephen23 am 26 Jul. 2017
Bearbeitet: Stephen23 am 26 Jul. 2017
You could use struct2cell:
C = struct2cell(output);
C = vertcat(C{:});
Note that the order of fields in a struct can change!
  3 Kommentare
Guillaume
Guillaume am 26 Jul. 2017
The order of the fields is defined by the order in which they were created.
s1 = struct('a', 1, 'b', 2)
c1 = struct2cell(s1)
s2 = struct('b', 2, 'a', 1)
c2 = struct2cell(s2)
For all intent and purpose s1 and s2 are identical, but the result of the conversion to cell array is not
isequal(s1, s2) %returns true. The structures are supposedly identical
isequal(c1, c2) %returns false. The cell array are definitively not the same
The cell arrays are ordered in the order of the fields as returned by fieldnames.
Stephen23
Stephen23 am 26 Jul. 2017
Bearbeitet: Stephen23 am 26 Jul. 2017
@Ioannis Agalliadis: You do not state what you are using to create those fields, so how am I supposed to know if they could be created in a different order by whatever creates them? Once they are are created then the order could be changed via orderfields. Therefore any code that assumes that the fields are in a particular order is going to be fragile unless you order them yourself just before converting to cell. My point is that struct2cell does not tell you if the fields have changed order or if any fields are missing/extra, therefore you need to make sure that your code is robust to these possibilities.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Structures finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by