我在想是否存在这样一个简单函数的名称,它返回数组中数字的顺序。我真的很想通过极简的方式和基本的 Unix 命令来进行这个排名,但除了基本的查找和循环之外,我无法想到任何东西,这不是那么优雅。假设你有一个数字数组
17
94
3
52
4
4
9
重复项仅收到相同 ID 的预期输出;如何处理重复项并不重要,因此可以走捷径:
4
6
1
5
2
2
3
动机:我今天看到许多用户使用许多不同的方法来解决这个问题,并使用电子表格执行许多手动步骤;所以我开始思考用极简主义的方式来做这件事。
将排名算法与 Google 的平均排名进行比较
在 Google 电子表格中,执行此操作=arrayformula(rank.AVG(A:A,A:A,true))
,您将得到作为升序的基准,如第一个预期输出
17 5
94 7
3 1
52 6
4 2.5
4 2.5
9 4
您可以看到我的初始排名算法有偏差。我认为能够设置数据集位置在这里会很有帮助。
答案1
如果该列表位于 a 中file
,每行一个,我会执行以下操作:
sort -nu file |
awk 'NR == FNR {rank[$0] = NR; next}
{print rank[$0]}' - file
如果它在zsh
$array
:
sorted=(${(nou)array})
for i ($array) echo $sorted[(i)$i]
这与上面版本的原理相同awk
,秩是按数字 ( / ) 排序 ( / )、唯一 ( / ) 的元素列表中的索引NR
/ 。(i)
-n
(n)
sort
(o)
-u
(u)
对于您的平均排名:
sort -n file |
awk 'NR == FNR {rank[$0] += NR; n[$0]++; next}
{print rank[$0] / n[$0]}' - file
这使:
5
7
1
6
2.5
2.5
4
(用于sort -rn
颠倒顺序,就像您的谷歌电子表格版本)。
答案2
nl x | sort -k 2n | nl | sort -k 2n | cut -f1
...在重复的情况下它的行为略有不同:
nl x | sort -k 2n | nl | sort -k 2n | cut -f1,3
5 17
7 94
1 3
6 52
2 4
3 4
4 9
答案3
仅使用 GNU awk:
awk '
FNR == NR {numbers[$1]=1; next}
FNR == 1 {
n = asorti(numbers, sorted, "@ind_num_asc")
for (i=1; i<=n; i++) rank[sorted[i]] = i
}
{print rank[$1]}
' file file