Keeping track of the Index while using "cell2mat" function

hey guys, I have a Cell Array a and am using cell2mat function for further clustering analysis, lets say:
a = {[1 2 3; 7 8 9], [4 5 6;10 11 12; 13 14 15]};
b = cell2mat(a(:));
rng(2)
k=2;
[idx] = kmeans(b,k);
which_in_cluster = cell(k,1);
for j = 1:k
which_in_cluster{j} = find(idx == j);
end
Cluster_1 = b(which_in_cluster{1,1},:); % 1st Cluster
Cluster_2 = b(which_in_cluster{2,1},:); % 2nd Cluster
Cluster_1 =
7 8 9
10 11 12
13 14 15
Cluster_2 =
1 2 3
4 5 6
I am now looking for a way to know in which Cell number and row these clusters have originally been in a. So in this example:
Cluster_1 =
7 8 9 % This has been in Cell number 1, row index 2 of a
10 11 12 % This has been in Cell number 2, row index 2 of a
13 14 15 % This has been in Cell number 2, row index 3 of a
Any help is greatly appreciated.

1 Comment

If anyone got an idea or can send me to the right direction, I'd really appreciate that.

Sign in to comment.

 Accepted Answer

key = cell2mat((arrayfun(@(IDX) [repmat(IDX, size(a{IDX},1), 1), (1:size(a{IDX},1).']) , 1:numel(a), 'uniform', 0));
Now index rows of key by the cluster number to get the cell number and row number.

7 Comments

Thanks for ur answer Walter, when trying to use ur code on the given example I get the error
Invalid Expression. When calling a function or indexing a variable, use parantheses. Otherwise, check for missmatched delimiters.
Putting this in:
key = cell2mat((arrayfun(@(idx) [repmat(idx, size(a{idx},1), 1), (1:size(a{idx},1).')] , 1:numel(a), 'uniform', 0)));
Gives me:
Error using horzcat
Dimensions of arrays being concatenated are not consistent
a = {[1 2 3; 7 8 9], [4 5 6;10 11 12; 13 14 15]};
key = arrayfun(@(idx) [repmat(idx,size(a{idx},1),1), (1:size(a{idx},1)).'], 1:numel(a), 'uniform', 0);
celldisp(key)
key{1} = 1 1 1 2 key{2} = 2 1 2 2 2 3
Ty, I'm still not quite sure how to read the output given by key.
key{1} is a 2x2 matrix. Cluster_1 is a 3x3 matrix. Not quite sure how the cell number and row number are extracted from key.
a = {[1 2 3; 7 8 9], [4 5 6;10 11 12; 13 14 15]};
b = cell2mat(a(:));
key = cell2mat(arrayfun(@(idx) [repmat(idx,size(a{idx},1),1), (1:size(a{idx},1)).'], (1:numel(a)).', 'uniform', 0))
key = 5×2
1 1 1 2 2 1 2 2 2 3
rng(2)
k=2;
[idx] = kmeans(b,k);
B = [b,key];
Cluster = cell(k,1);
for j = 1:k
which_in_cluster{j} = find(idx == j);
Cluster{j} = B(idx == j,:);
end
celldisp(Cluster)
Cluster{1} = 7 8 9 1 2 10 11 12 2 2 13 14 15 2 3 Cluster{2} = 1 2 3 1 1 4 5 6 2 1
Last two columns are cell index in a, then row number within that cell entry.
Thank you Walter, my original question has been answered but I do have a follow up question on this if you don't mind. I can post this in a new question if you wish so.
I exctracted the last 2 Columns from the first Cell of Cluster
c = Cluster{1};
IDX2 = c(:,end-1:end)
IDX2 =
1 2 % Cell 1 - Row 2
2 2 % Cell 2 - Row 2
2 3 % Cell 2 - Row 3
I now have another Cell Array, with the same size as a (only consisting of nx1 matrices). For example:
f = {[1;2],[2;3;4]}
>> celldisp(f)
f{1} =
0.5
0.2
f{2} =
0.7
0.9
0.8
How can I now extract the corresponding numbers from f (they represent the frequencies in my analysis) from the information represented in IDX2?
so, that the output would look something like this:
F =
0.2000
0.9000
0.8000
F = arrayfun(@(R) f{IDX2(R,1)}(IDX2(R,2)), (1:size(IDX2,1).'))
This is probably one of the cases where it is just clearer to write a loop, and probably more efficient:
nrow = size(IDX2,1);
F = zeros(nrow,1);
for K = 1 : nrow
F(K) = f{IDX2(K,1)}(IDX2(K,2));
end

Sign in to comment.

More Answers (0)

Tags

Asked:

on 15 Jan 2021

Commented:

on 18 Jan 2021

Community Treasure Hunt

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

Start Hunting!