MATLAB Answers

0

How to group rows of data into a cell of a cell array?

Asked by John Hunt on 17 Oct 2017
Latest activity Answered by Walter Roberson
on 17 Oct 2017
I have a data that has xyz information as well as three numbers that group each point together. As an example a row might have [ -1 2 -4 1 2 15] So that atom is at point (-1,2,-4) and it is defined by 1,2,and 15. There is an unknown amount of atoms that have different locations but have the same defined numbers. I want to group all of the atoms that have the same 3 defining numbers in a matrix that is in a cell array (or into structure if that is easier) QN. I have the following code but I am not adding more data to one cell. This is what I have
j=1;
for k = 1:(length(TypesQN)-1)
for p = 1:(length(locQN)-1)
if TypesQN(k,1:4)==locQN(p,4:7)
qn=locQN(p,:);
QN{j}=qn;
j=j+1;
end
end
end
Where the amount of defined numbers is know (TypesQN) and the total dataset length is known (locQN).

  0 Comments

Sign in to comment.

Tags

2 Answers

Answer by Cedric Wannaz
on 17 Oct 2017
Edited by Cedric Wannaz
on 17 Oct 2017
 Accepted Answer

Here is one way. We start by building a fake data set:
>> A = [rand(10,3), randi(2,10,3)]
A =
0.7513 0.8407 0.3517 1.0000 1.0000 1.0000
0.2551 0.2543 0.8308 1.0000 2.0000 1.0000
0.5060 0.8143 0.5853 2.0000 1.0000 1.0000
0.6991 0.2435 0.5497 2.0000 2.0000 2.0000
0.8909 0.9293 0.9172 2.0000 1.0000 1.0000
0.9593 0.3500 0.2858 1.0000 2.0000 2.0000
0.5472 0.1966 0.7572 2.0000 1.0000 2.0000
0.1386 0.2511 0.7537 1.0000 2.0000 2.0000
0.1493 0.6160 0.3804 1.0000 2.0000 1.0000
0.2575 0.4733 0.5678 1.0000 2.0000 1.0000
Then we find group IDs per unique combination of 3 "ID" numbers:
>> [~,~,gId] = unique( A(:,4:end), 'rows' )
gId =
1
2
4
6
4
3
5
3
2
2
and we use these to split the array:
>> groups = splitapply( @(x){x}, A, gId )
groups =
6×1 cell array
{1×6 double}
{3×6 double}
{2×6 double}
{2×6 double}
{1×6 double}
{1×6 double}
where you can see that the 3 numbers are the same for e.g. group 2:
>> groups{2}
ans =
0.2551 0.2543 0.8308 1.0000 2.0000 1.0000
0.1493 0.6160 0.3804 1.0000 2.0000 1.0000
0.2575 0.4733 0.5678 1.0000 2.0000 1.0000
Note that if you don't want to save the ID numbers in the groups, you can split as follows:
>> groups = splitapply( @(x){x(:,1:3)}, A, gId )
groups =
6×1 cell array
{1×3 double}
{3×3 double}
{2×3 double}
{2×3 double}
{1×3 double}
{1×3 double}
>> groups{2}
ans =
0.2551 0.2543 0.8308
0.1493 0.6160 0.3804
0.2575 0.4733 0.5678

  0 Comments

Sign in to comment.


Answer by Walter Roberson
on 17 Oct 2017

TypesQN = [randi([-5 5],1000,3), randi(5,1000,3)]; %sample data for testing
[~, ~, group_number] = unique(TypesQN(:,4:6), 'rows');
grouped_atoms = splitapply(@(M) {M}, TypesQN, group_number);
The above requires R2015b or later; if you have an earlier version then the splitapply can be rewritten to other code.

  0 Comments

Sign in to comment.