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

조회 수: 22 (최근 30일)
John Hunt
John Hunt 2017년 10월 17일
댓글: Walter Roberson 2022년 3월 12일
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).

채택된 답변

Cedric
Cedric 2017년 10월 17일
편집: Cedric 2017년 10월 17일
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
Walter Roberson
Walter Roberson 2022년 3월 12일
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)
ans = 2×2 cell array
{'Female'} {[6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6]} {'Male' } {[ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4]}

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Walter Roberson
Walter Roberson 2017년 10월 17일
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.

카테고리

Help CenterFile Exchange에서 MATLAB Report Generator에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by