使用Pandas的mergesort先后排序列与索引是否稳定有效?
问题描述
现有如下结构的Pandas DataFrame(i1、i2、i3为多层索引列,A、B为普通列):
'A' 'B' 'i1' 'i2' 'i3' 1 2 4 3 0 1 1 2 3 3 1 1 2 1 0 1 2 4 0 9 1 1 2 2 6 2 1 1 1 8
需求:先按索引严格排序,当索引重复时,按A列升序排列,目标结果如下:
'A' 'B' 'i1' 'i2' 'i3' 1 1 2 1 0 1 1 2 2 6 1 1 2 3 3 1 2 4 0 9 1 2 4 3 0 2 1 1 1 8
请问执行df.sort_values('A', kind='mergesort').sort_index(kind='mergesort')能否实现该需求?该方式是否稳定?sort_index是否会破坏之前sort_values的结果,导致重复索引对应的A列不再有序?
解答
1. 给定代码能否实现需求?
可以实现。具体逻辑:
- 第一步
df.sort_values('A', kind='mergesort')会将全量数据按A列升序排列,由于使用了归并排序(稳定排序),相同A值的行将保留原有相对顺序,但此时数据还未按索引排序。 - 第二步
sort_index(kind='mergesort')对多层索引执行稳定排序:稳定排序的核心特性是,当排序键(此处为索引)的值相同时,会保留这些行在之前排序后的相对位置。由于第一步已经将同一索引组内的行按A列排好序,稳定的索引排序会完整保留同一索引下A列的有序性,最终得到符合需求的结果。
2. 该方式是否稳定?
整个排序过程是稳定的。因为两次排序都指定了kind='mergesort':
- 归并排序属于稳定排序算法,本质是当排序键值相同时,不会改变数据原有的相对顺序。
- 第一次按
A列稳定排序,确保相同A值的行相对位置不变;第二次按索引稳定排序,确保同一索引的行保留之前按A列排好的顺序,全程不会打乱已有的有序性。
3. sort_index是否会破坏之前sort_values的结果?
不会。因为使用了稳定的归并排序进行索引排序:当多行的索引完全相同时,这些行的相对顺序会严格保持它们在sort_values后的状态——也就是按A列升序的顺序。如果换成非稳定排序(比如默认的quicksort),同一索引下的行顺序才可能被打乱,但mergesort不会出现这个问题。
补充:更简洁高效的写法可以直接合并排序逻辑,比如
df.sort_values(['i1','i2','i3','A']),但给定的写法确实能达成需求。
内容的提问来源于stack exchange,提问作者Thelemitian
相关产品推荐
相关产品推荐

