how to construct a cell array from another cell array

I have a cell array with a variable number of cells and a variable number of elements within each cell. For instance, it could by V{1}{1}=1 2 3 4, V{1}{2}=3 4 1 0,V{1}{3}=3 5 -1 -9, and V{2}{1}=-1 -2 9, V{2}{2}= 0 9 6, i.e., the cell 1 has 3 vectors of length 4 elements and the cell 2 has 2 vectors of length 3. I want to construct another cell array such that it has all combinations of these vectors, here I could have 6 combinations (3*2=6). The new cell array has to be of length 6 cells (number of possible combinations), and each cell has a possible combinations, for example A{1}={1 2 3 4 and -1 -2 9} and A{2}={1 2 3 4 and 0 9 6} . Note that I will get these vectors from a matlab code so I do not know them in advance.

3 个评论

It would be easier if we had data to play with (instead of having to construct fake data ourselves and risk getting it wrong).
Hi Adam. The numbers are not important. Imagine we have a cell array of some length V{1}{1}=vec1, V{1}{2}=vec2, V{1}{3}=vec3, and also we have V{2}{1}=vec4, V{2}{2}=vec5, From the array V, I want to construct another cell array, SAY D, which ha all possible combinations of vectors {vec1, vec2,vec3} and {vec4,vec5}. However, we can not combine two vectors from the same set, e.g., we can not have vec1 and vec2 combined. I wand the cell array D to be for example D{1}{1}=vec1 and D{1}{2}=vec4. I hope this helps
I set up some demo data "V" that fits your description and the output "D" also fits your description (see answers). If this doesn't fit your goal, please update us on how your data or your goal differs.

请先登录,再进行评论。

 采纳的回答

This fits the description from your comment under your question. It horizontally concatenates all combinations of the row vectors stored in V{1} and V{2}.
% Demo data
V{1}{1} = 1:4; % vec1 1x4
V{1}{2} = 2:5; % vec2 1x4
V{1}{3} = 3:6; % vec3 1x4
V{2}{1} = 1:3; % vec4 1x3
V{2}{2} = 2:4; % vec5 1x3
[v1idx, v2idx] = ndgrid(1:numel(V{1}), 1:numel(V{2}));
D = cellfun(@(a,b)horzcat(a,b),{V{1}{v1idx(:)}}, {V{2}{v2idx(:)}}, 'UniformOutput', false)
% D = {[vec1,vec4], [vec2,vec4], [vec3,vec4], [vec1,vec5], [vec2,vec5], [vec3,vec5]}
Version 2: when number of sub-cells in V is variable.
cellCount = num2cell(1:numel(V));
nCellIdx = cellfun(@(x)1:numel(x), V, 'UniformOutput', false);
cellGrid = cell(size(nCellIdx));
[cellGrid{:}] = ndgrid(nCellIdx{:});
matGrid = cell2mat(cellfun(@(x)x(:),cellGrid,'UniformOutput',false)); % Each row is the index for 1 cell
D = cell(1,size(matGrid,1));
for i = 1:size(matGrid,1)
D{i} = cellfun(@(ci,sci)V{ci}(sci),cellCount, num2cell(matGrid(i,:)));
end
D(i) contains the sub-cell indices listed in matGrid(i,:).

10 个评论

This should work, also @(a,b)horzcat(a,b) can be replaced by @horzcat
Thanks madhan!
I don't know why but I'm always inclined to add the function input arguments. Bad habit, maybe?
@ mohamed, as madhan pointed out, the last line can be simplified a bit as seen below.
D = cellfun(@horzcat,{V{1}{v1idx(:)}}, {V{2}{v2idx(:)}}, 'UniformOutput', false)
"Bad habit, maybe?"
Not at all, it'll change through time.
Thank you Adam Danz and madhan ravi, The array D has to be {[vec1;vec4], [vec2;vec4], [vec3;vec4], [vec1;vec5], [vec2;vec5], [vec3;vec5]}. Also, the code must be general since the size of V could change in every run. In this case, I might have another cell for V, e.g., V{3}, so this [v1idx, v2idx] = ndgrid(1:numel(V{1}), 1:numel(V{2} will not work.
"The array D has to be {[vec1;vec4],..."
That won't be possible. Vec1 and Vec4 must have the same number of elements. In your description, these vectors do not have the same number of elements. So, you can't have
[1 2 3 4;
1 2 3]
% Error: Dimensions of arrays being concatenated are not consistent.
You could pad the shorter vector with NaNs,
[1 2 3 4;
1 2 3 NaN]
"In this case, I might have another cell for V, e.g., V{3}"
So, would you expect this below?
[vec1
vec2
vec3] % assuming they are all equal length or have padding
This might help to understand the problem
I have an array like this, i.e., it has two cells (we could have more cells) and the size of the first cell is 3 by N (length of vectors 1, 2 and 3) and the size of cell 2 is 2 by M (length of vectors 4 and 5). I want to construct an array that has all the possible combiations of vectors from the sets . However, we can not have two vectors from the same set, e.g., we can not hav vector 1 and vector 2 in the same cell. The result shlud be like this . Thus D should have 3*2=6 cells and each cell has two elements (vectors). Note that I will not enter the array V myself, it is generated by another matlab code so the code has to figure out the size of V and the length of all vectors if needed.
"I have an array like this, ....., it has two cells (we could have more cells) and the size of the first cell is 3 by N (length of vectors 1, 2 and 3) and the size of cell 2 is 2 by M (length of vectors 4 and 5). "
The size of cell 2 is not [2 x M], it's [1 x M] (assuming vector4 and vector5 are row vectors). Vector 4 and 5 are separated by a comma, not a semicolon. That means they are horizontally concatenated, not vertically.
It may be helpful to provide multiple examples with actual data.
Below is information about my cell array. Its name is "allPaths_service"
>> allPaths_service
allPaths_service =
{5x1 cell} {3x1 cell} {3x1 cell}
********************************************
>> size(allPaths_service)
ans =
1 3
********************************************
>> allPaths_service{:}
ans =
[1x6 double]
[1x6 double]
[1x6 double]
[1x6 double]
[1x6 double]
ans =
[1x5 double]
[1x5 double]
[1x5 double]
ans =
[1x5 double]
[1x5 double]
[1x5 double]
********************************************
>> allPaths_service{1}{:}
ans =
1 2 3 4 5 10
ans =
1 2 3 4 9 10
ans =
1 6 7 4 5 10
ans =
1 6 7 4 9 10
ans =
1 6 7 8 9 10
********************************************
>> allPaths_service{2}{:}
ans =
1 2 3 5 10
ans =
1 6 7 5 10
ans =
1 6 7 9 10
********************************************
>> allPaths_service{3}{:}
ans =
1 2 3 5 10
ans =
1 6 7 5 10
ans =
1 6 7 9 10
********************************************
Please note that this array is generated from another matlab code, so it may change size
Could you save "allPaths_service" to a mat file and attach it?
Also, could you provide a small example of the expected outcome (using real data). I know it would take time to manually produce the entire output but a few combinations would be helpful. For example, it's still unclear how a 1xn vector will be combined with a 1xm vector.
I updated my answer with "version 2". It still uses ndgrid() but is not dependent on knowing how many subcells are in "V". Tested with your data successfully.

请先登录,再进行评论。

更多回答(1 个)

Hi Adam. Attached is the cell array allPaths_service. I also created a cell array DD which has two possible combinations from allPaths_service.

1 个评论

Thank you Adam. Thi s was very helpful. One last thing. I noticed that t
matGrid =
1 1
2 1
3 1
1 2
2 2
3 2
what if I want ti to be in this order
matGrid =
1 1
1 2
2 1
2 2
3 1
3 2
which means we first change the index of the right most column first.

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Creating and Concatenating Matrices 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by