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

8 次查看(过去 30 天)
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.

采纳的回答

Titus Edelhofer
Titus Edelhofer 2018-9-3
编辑:Titus Edelhofer 2018-9-4
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 个评论
bryan
bryan 2018-9-4
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']

请先登录,再进行评论。

更多回答(1 个)

MF
MF 2018-9-3
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 个评论
bryan
bryan 2018-9-4
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.
MF
MF 2018-9-4
编辑:MF 2018-9-4
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.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Matrix Indexing 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by