How to group rows of data into a cell of a cell array?
21 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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 commentaires
Réponse acceptée
Cedric
le 17 Oct 2017
Modifié(e) : Cedric
le 17 Oct 2017
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
4 commentaires
Walter Roberson
le 12 Mar 2022
splitapply can be used for cell arrays as well, and it is not limited to doing arithmetic computations on the fields. For example, the following gets the T.Gender fields and for each one takes length() [which would happen to be consistent for each gender]
What datatype do you need to work with? What non-numeric fields do you need to apply functions to?
load patients
T = table(Gender,Height);
[G,gender] = findgroups(T.Gender);
splitapply(@(x) {x{1}, cellfun(@length,x.')}, T.Gender, G)
Plus de réponses (1)
Walter Roberson
le 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 commentaires
Voir également
Catégories
En savoir plus sur Data Preprocessing dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!