字典数组排序平局处理:为含数组的字典添加rank键
解决方案:按多键排序并添加排名
我来帮你搞定这个需求!要给字典添加rank键,实现先按'a'排序、平局时按'b'排序的排名逻辑,我们可以借助NumPy的工具一步步完成:
第一步:获取多键排序的索引
首先要得到符合「先按'a'排序,'a'相同时按'b'排序」规则的索引,这里用np.lexsort()最方便——它会按传入数组的从右到左优先级排序,所以我们把次要排序键('b')放在前面,主要排序键('a')放在后面:
import numpy as np to_sort={'a':np.array([1,1,3]),'b':np.array([5,4,5])} # 获取排序索引:先按'a'升序,再按'b'升序 sort_indices = np.lexsort([to_sort['b'], to_sort['a']]) # 输出结果:array([1, 0, 2], dtype=int64)
这个索引数组表示:原字典中索引1的元素排第1位,索引0排第2位,索引2排第3位,完美符合我们的排序规则。
第二步:计算排名并添加到字典
接下来是排名处理,这里分两种常见场景:
场景1:顺序排名(连续不重复)
如果需要给每个元素按排序后的位置分配连续排名(即使'a'相同,只要'b'不同就有不同排名),可以直接通过索引映射生成排名数组:
# 创建与数组长度一致的空排名数组 rank_array = np.zeros(len(to_sort['a']), dtype=int) # 给排序后的每个位置分配排名(从1开始) rank_array[sort_indices] = np.arange(1, len(rank_array)+1) # 将排名添加到字典 to_sort['rank'] = rank_array
最终to_sort['rank']的结果是array([2, 1, 3]),对应原索引0排第2、索引1排第1、索引2排第3,完全匹配排序逻辑。
场景2:相同'a'共享排名(跳跃式)
如果希望所有'a'值相同的元素共享同一个排名(不管'b'的值),可以用np.unique()来实现:
# 获取'a'的唯一值及逆映射,逆映射的结果加1就是排名 _, inverse = np.unique(to_sort['a'], return_inverse=True) rank_array = inverse + 1 to_sort['rank'] = rank_array
这种情况下,to_sort['rank']的结果是array([1, 1, 2]),所有'a'=1的元素排名都是1,'a'=3的元素排名是2。
完整示例代码
如果需要升序排序的顺序排名,完整代码如下:
import numpy as np to_sort={'a':np.array([1,1,3]),'b':np.array([5,4,5])} # 1. 获取多键排序索引 sort_indices = np.lexsort([to_sort['b'], to_sort['a']]) # 2. 生成顺序排名数组 rank_array = np.zeros(len(to_sort['a']), dtype=int) rank_array[sort_indices] = np.arange(1, len(rank_array)+1) # 3. 添加到字典 to_sort['rank'] = rank_array # 查看最终结果 print(to_sort)
输出结果:
{'a': array([1, 1, 3]), 'b': array([5, 4, 5]), 'rank': array([2, 1, 3])}
如果需要降序排序,只需要在排序数组前加负号即可,比如按'a'降序、'b'降序:
sort_indices = np.lexsort([-to_sort['b'], -to_sort['a']])
内容的提问来源于stack exchange,提问作者00__00__00
相关产品推荐
相关产品推荐

