我有一个160x2 MATLAB双,结构如下
| Vocab | Math
-------------------------
1 | 1 | 1
2 | 3 | 4
3 | 4 | 3
4 | 2 | 2
在上面的例子中,我简化了一些事情,所以它只有4x2而不是160x2。
每列代表学生评分的两个班级之一。
在Vocab上,人1排名第一,然后是人3,然后是人4,然后是第2人。
在数学方面,人1排名第一,然后是人4,然后是人3,然后是第2人。
我想实现一个整体排名系统,将每个人的结果组合在两个班级上,并将整体排名设为第三列。
我希望编写灵活的代码,以便将数学加权比Vocab更重要。让我们说它的价值是Vocab的两倍。
我知道权重可以通过积分系统完成,其中较少的积分意味着更好的结果。
第1人在Vocab和Math方面表现最佳,Vocab排名获得1分,数学排名= 2分(因为数学加权加倍)= 3总
人物2在Vocab和数学上都是最差的(第四名),Vocab排名获得4分,数学排名获得8分= 总共12名
人3获得2分为Vocab,6分为数学= 8总
人4获得Vocab 3分,Math = 7总<4分
根据这些得分,应该更改双倍以添加一列来表示总体排名:
| Vocab | Math |Overall
-------------------------
1 | 1 | 1 | 1
2 | 3 | 4 | 4
3 | 4 | 3 | 3
4 | 2 | 2 | 2
如何在MATLAB中有效地实现这一目标?
我想编写代码,允许将来灵活地更改权重,以便(例如)数学的价值是Vocab的三倍。但是,我永远不需要添加更多科目 - 它将永远只是词汇和数学。
我希望能够决定支持数学上得分更高的人。
答案 0 :(得分:2)
这是accumarray
的经典任务:
%// persons
p = [1 2 3 4];
%// rank of person in each classes
%// class 1, class 2, class 3
c = [ 1 1 4 ;
3 3 2 ;
4 4 1 ;
2 2 3 ];
%// weights of classes
w = [1 2 3];
%// score table
s = bsxfun(@mtimes,ndgrid(1:size(c,1),1:size(c,2)),w)
%// sum up points per person
ppp = accumarray(c(:),s(:))
%// overall ranking with class 3 as decisive row in case of tie
[~,o] = sortrows([ppp c(:,3)],[1 2])
%// overall rank of persons in order of person id
[~,r] = sort(o)
%// output
out = table(p(:),r, c, ppp, o,'VariableNames',{'person','rankOfPerson','classes', ...
'OverallPointsOfPerson','overallRanking'})
out =
person rankOfPerson classes OverallPointsOfPerson overallRanking
______ ____________ ___________ _____________________ ______________
1 2 1 1 4 12 4
2 4 3 3 2 18 1
3 3 4 4 1 18 3
4 1 2 2 3 12 2