在未知所有值的情况下对Pandas DataFrame进行自定义首尾排序
解决方案:Pandas分组固定首尾行排序
给定如下结构的Pandas DataFrame:
id desc amount 356 89 2521 ShouldBeFirst 0.00 356 89 2521 ShouldBeLast 19.00 356 89 2521 RandomValue 39.00 356 89 2521 RandomValue2 29.00 123 45 6789 RandomValue3 29.99 123 45 6789 ShouldBeFirst 0.00 123 45 6789 ShouldBeLast 99.00 123 45 6789 RandomValue3 39.00 123 45 6789 RandomValue2 19.00
需要实现:
- 先按
id列升序排序 - 每个
id分组内,首行固定为desc值等于ShouldBeFirst的行,末行固定为desc值等于ShouldBeLast的行,中间行无需指定所有desc取值即可排序
目标效果:
id desc amount 123 45 6789 ShouldBeFirst 0.00 123 45 6789 RandomValue2 19.00 123 45 6789 RandomValue3 29.99 123 45 6789 RandomValue3 39.00 123 45 6789 ShouldBeLast 99.00 356 89 2521 ShouldBeFirst 0.00 356 89 2521 RandomValue2 29.00 356 89 2521 RandomValue 39.00 356 89 2521 ShouldBeLast 19.00
实现步骤
- 按
id升序排序整个DataFrame - 为每行生成排序优先级键:
ShouldBeFirst行键设为0(最高优先级,排最前)ShouldBeLast行键设为2(最低优先级,排最后)- 其他行键设为1(中间区域)
- 按
id和排序键分组排序,中间行可保留原顺序或按需调整
代码实现
import pandas as pd # 构造示例DataFrame data = { 'id': ['356 89 2521', '356 89 2521', '356 89 2521', '356 89 2521', '123 45 6789', '123 45 6789', '123 45 6789', '123 45 6789', '123 45 6789'], 'desc': ['ShouldBeFirst', 'ShouldBeLast', 'RandomValue', 'RandomValue2', 'RandomValue3', 'ShouldBeFirst', 'ShouldBeLast', 'RandomValue3', 'RandomValue2'], 'amount': [0.00, 19.00, 39.00, 29.00, 29.99, 0.00, 99.00, 39.00, 19.00] } df = pd.DataFrame(data) # 按id升序排序 df_sorted = df.sort_values('id', ascending=True) # 生成排序键 df_sorted['sort_key'] = df_sorted['desc'].map( lambda x: 0 if x == 'ShouldBeFirst' else 2 if x == 'ShouldBeLast' else 1 ) # 按id和sort_key排序,使用mergesort保证中间行原顺序稳定 result = df_sorted.sort_values(by=['id', 'sort_key'], kind='mergesort').drop('sort_key', axis=1) print(result)
说明
- 无需枚举所有
desc取值,仅需指定首尾行的标识值即可生成排序规则 kind='mergesort'为稳定排序,能保留中间行原有相对顺序;若不需要原顺序,可去掉该参数或改为按amount等字段排序- 最后删除临时的
sort_key列,得到目标结果
内容的提问来源于stack exchange,提问作者Jose Vega
相关产品推荐
相关产品推荐

