我希望能够根据向量的大小为向量中的数字分配等级,并创建一个包含这些等级的新向量。
例如,如果我有 vector [5, 2, 3, 1]
,我想返回[4, 2, 3, 1]
(因为 5 是最大的数字,1 是最小的数字)。相同的数字最好共享一个平均排名(例如,如果两者相同并且是最低的,则它们的平均排名应该为 1.5)。
如何在 MATLAB 中实现这一点?
我建议您不要使用排序,而是使用unique
:
[~, ~, ranking] = unique(x);
它还对向量进行排序,但将相同的值映射到相同的索引。这样,原始向量中的相同元素将获得相同的排名。例如,如果x = [5 2 3 1 3]
,我们得到:
ranking =
4 2 3 1 3
如果您想要一个“平均”排名,您可以accumarray
结合使用从unique
和 从获得的信息sort
,因此请执行以下操作:
[~, ~, idx_u] = unique(x);
[~, idx_s] = sort(x);
mean_ranks = accumarray(idx_u(:), idx_s(idx_s), [], @mean);
ranking = mean_ranks(idx_u);
在我们的示例中,我们会得到:
ranking =
1.0000
2.0000
3.5000
5.0000
3.5000
请注意,两个值 3 的平均排名均为 3.5,因为它们共享排名 3 和 4。
你可以使用第二个输出参数sort()
来做你想做的事。
例如(在 Matlab 2011b 中测试)
>> [~,ranking] = sort([5 2 3 1]);
>> ranking
ranking =
4 2 3 1
编辑:(OP要求进一步解释)
从您的示例中,我确定更高的排名会出现更大的数字,因此如果列表已排序,它本质上是值的位置。
调用sort( )
将列表按升序排序。排序后的列表是返回的第一件事。我放了一个~
,因为我们并不真正关心排序列表,所以我们只是把值扔掉了。
的第二个输出参数sort
是未排序列表到已排序列表的映射。也就是说,对于未排序列表中的每个项目,它都会给出其在已排序列表中的位置。
再次编辑: 听起来您想要从您的描述中获得“分数排名”。据我所知,Matlab 中没有内置任何东西可以直接执行此操作,但是 FEX 上有文件。我从未使用过它们,但有一个具有全面描述的,所以它似乎是一个不错的选择:排名 - 文件交换
如果您有统计和机器学习工具箱,那么您可以使用 Matlab 内置函数tiedrank
:
>> ranking = tiedrank([5 2 3 1 3]);
>> ranking
ranking =
5.0000 2.0000 3.5000 1.0000 3.5000