MATLAB Answers

0

How to delete rows from a cell array that do not satisfy a certain condition?

Hi all, I have a problem where I am generating the combinations of people from one group with the people in another group. Each person comes with a name obviously and a Score which is of particular interest. In order to make the combinations fair, the combined scores cannot exceed a maximum value.
NameA='bob'
ScoreA=1000
A={NameA, ScoreA}
NameB='mike'
ScoreB=2000
B={NameB, ScoreB}
GROUP1={'A','B'}
NameC='harry'
ScoreC=500
C={NameC, ScoreC}
NameD='TED'
ScoreD=100
D={NameD, ScoreD}
GROUP2={'C', 'D'}
GROUPS={GROUP1 GROUP2}
[x y] = ndgrid(GROUPS{:})
GROUPScombs = [x(:) y(:)]
GROUPScombs yields 4x2 cell array 4×2 cell array
{'A'} {'C'}
{'B'} {'C'}
{'A'} {'D'}
{'B'} {'D'}
Now at this point I have generated the total combinations but I want to delete the rows where the combined scores are over 2000. So for example Score A + Score C = 1500, so row 1 is good. However, score B+C=2500 which is over 2000 so I would like to delete that row. Not sure how to use MATLAB to easily perform this calculation. Row 3 is good and Row 4 should be eliminated. Thank you.

답변 수: 2

Titus Edelhofer 님의 답변 3 Sep 2018
Titus Edelhofer 님이 편집함. 4 Sep 2018
 채택된 답변

Hi,
things get much easier, if you use arrays instead of individual variable names:
% combine names and scores into a table
t = table({'bob'; 'mike'; 'harry'; 'TED'}, [1000 2000 500 100]', ...
'VariableNames', {'Name', 'Score'});
% define your (sub-)groups as you did
groups1 = 1:2;
groups2 = 3:4;
[x,y] = ndgrid(groups1, groups2);
GROUPScombs = [x(:) y(:)]
% now grab from the table the scores as in your combinations:
scores = reshape(t{GROUPScombs, 'Score'}, size(GROUPScombs));
% sum the two columns
scoresSum = sum(scores, 2);
% and select
alledCombs = GROUPScombs(scoresSum<=2000, :)
% and get the corresponding names:
alledNames = reshape(t{alledCombs, 'Name'}, size(alledCombs))
Titus

  댓글 수: 2

Thank you Titus! This works well. If I could bug you more, is there any easy way to convert alledCombs indices back into a matrix of the actual names? In other words, the result of alledCombs is [1,3;1,4] and I would like to display it as ['bob','harry';'bob','TED']
Added one line to retrieve the names ...

로그인 to comment.


MF 님의 답변 3 Sep 2018

This is definitely not the most optimal solution, but it works. Firstly, create a matrix of scores that correspond to each person in GROUPScombs cell array.
for i = 1:size(GROUPScombs,1)
for j = 1:size(GROUPScombs,2)
if GROUPScombs{i,j}=='A'
RESULTScombs(i,j)=1000;
elseif GROUPScombs{i,j}=='B'
RESULTScombs(i,j)=2000;
elseif GROUPScombs{i,j}=='C'
RESULTScombs(i,j)=500;
else
RESULTScombs(i,j)=100;
end
end
end
Sum the results row-wise.
sumResults=sum(RESULTScombs,2)
Keep only the pairs, whose scores sum is equal to or lower than 1500.
GROUPScombsNew=GROUPScombs(find(sumResults<=1500),:)
Hope this helps.

  댓글 수: 2

Thank you MF! Similar to my above question to Titus, is there a way to unpack the result of GROUPScombsNew which is {'A'} {'C'};{'A'}{'D'} such that it shows the names? I'm a newbie.
Here is the solution. Again, not optimal, but it works. Loop through all the entries in alledCombs, transform the numbers to the corresponding names and then write them in a cell alledCombs2. Please note that j index refers to columns and index i to the rows of the alledCombs matrix.
k=1
for j=1:size(alledCombs,2)
for i=1:size(alledCombs,1)
alledCombs2{k}=t.Name{alledCombs(i,j)}
k=k+1;
end
end
Please do not forget to accept the answer by Titus/me, if you think that your question was answered properly.

로그인 to comment.



Translated by