How to delete rows from a cell array that do not satisfy a certain condition?
4 次查看(过去 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
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
更多回答(1 个)
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 个评论
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 Center 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!