求一个美式排名的写法
大佬们,我想求助一个美式排名的写法。数据源如下所示,可复制使用:
A | B | |
1 | C | 88 |
2 | D | 98 |
3 | E | 78 |
4 | F | 90 |
5 | G | 95 |
6 | H | 98 |
7 | I | 91 |
8 | J | 90 |
9 | K | 79 |
10 | L | 95 |
想得到一个美式排名,结果如下所示:
=spl("=R=(X=?).ranks@z(~2),X.group@p(-~2).conj(~.(X(~)|R(~)))",B4:C13)
我写的是先用 ranks@z 得到美式排名的结果 R,然后用 group@p 返回位置后,再用位置分别从源序列和排名序列 R 中深化出结果。这个写法效率能接受,比如把数据源扩大 10 万倍,在插件中也能在 10 秒左右跑出结果。这样写分了两步,先求排名再去拼接出结果。我想着能不能在一句话中解决,于是就有了以下写法:
=spl("=(X=?).group@p(-~2).conj(~.(X(~)|(get(1;:-1).conj().len()+1)))",B4:C13)
发现语句既没有变简洁,执行速度反而更慢了,因为 get(1;:-1) 这部分的原因,随着位移区间变大,效率也变慢。这个写法的思想其实很朴素,get(1;:-1).conj().len() 这部分其实就是得到比当前值大的数有多少个,这个复杂度貌似无异于全表遍历。
如果是中式排名,之前老贼在一篇帖子中有教过怎么写: Excel 按顺序去重再编号
这种让人拍案叫绝的写法,确实让我受益良多。
所以,我想恳请大佬们指点一下,这种美式排名有没有较好 (高效) 的写法,谢谢🙏 🙏
在 excel 中要写成一句可以这样:
如果写在 spl 脚本里分步用 ranks 比较省事
谢谢大佬出手指导,学到了👍 👍 👍
1、~3=~[-1](3) 这部分很独到,豁然开朗,我思维太狭隘了,一直困惑在 get(1;:-1)。
2、sort 和 ranks 其实也很快 (对 sort 一直有阴影)…这样一来反而更简洁易懂。
?.ranks@z(~2).(?(#)|~).sort(~3)
😂 握艹…牛👍 👍 👍 …谢谢老贼出手🙏