如何对pandas Series按值排序时随机化等值元素的顺序?
随机化pandas Series排序中等值元素的顺序
好问题!确实pandas自带的quicksort、mergesort、heapsort这些排序算法要么是稳定排序(保持原顺序),要么有固定的排序逻辑,没法直接打乱等值元素的顺序。不过有几个现成的简便方法可以实现需求,不用自己写复杂的自定义函数:
方法一:添加微小随机扰动(简单高效)
给每个元素加上一个极小的随机数,这个随机数小到不会改变不同数值之间的大小关系,但能打乱等值元素的排序顺序。如果想保留原数值的精度,可以只通过扰动后的序列获取排序索引,再重新索引原Series:import pandas as pd import numpy as np s = pd.Series([3.0, 15.0, 1.0, 22.0, 11.0, 12.0, 2.0, 5.0, 3.0, 12.0, 2.0, 3.0]) # 生成扰动后的序列,获取排序索引,再用原Series重新索引 shuffled_index = s.add(np.random.uniform(-1e-9, 1e-9, size=len(s))).sort_values(ascending=False).index s_shuffled = s.loc[shuffled_index]这样得到的
s_shuffled里,等值元素的顺序就是随机的,而且数值完全和原Series一致。方法二:分组后打乱组内顺序(逻辑更清晰)
先按Series的值分组,对每个组(也就是所有等值元素)随机打乱顺序,再整体按值降序排列:# 分组后每组内随机打乱,再合并排序 groups = s.groupby(s).apply(lambda x: x.sample(frac=1)) s_shuffled = groups.sort_values(ascending=False)sample(frac=1)的作用就是对每组内的元素进行随机重排,这种方法完全不用担心精度问题,逻辑也更直观。方法三:利用sort_values的key参数(pandas 1.1.0+)
如果你的pandas版本在1.1.0及以上,可以直接用key参数生成随机排序键,一步到位:s_shuffled = s.sort_values(ascending=False, key=lambda x: x + np.random.uniform(0, 1e-9, size=len(x)))这个方法本质和方法一类似,只是借助
key参数简化了代码。
你可以根据自己的pandas版本和偏好选择合适的方法,测试几次就能看到等值元素的顺序每次都不一样啦~
内容的提问来源于stack exchange,提问作者Truls Møller
相关产品推荐
相关产品推荐

