You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在pandas DataFrame中按多规则对同组正负值排序,含Separate CY列排序需求

实现方法

首先对原始数据做预处理,将Separate CY、Separate PY列从字符串转换为整数类型,再构造排序辅助列实现多规则排序,完整可运行代码如下:

import pandas as pd

# 构造原始DataFrame
df = pd.DataFrame({
    "Ref":["NFS", "NFS", "NFS-3M", "NFS-3M", "NFS-3M", "NFS-3M", "NFS-3M", "NFS-3M", "NFS-3M", "NFS-3M", "NFS-3M", "NFS-3M", "NFS-3M", "NFS", "NFS", "NFS", "NFS", "NFS", "NFS", "NFS-3M", "NFS-3M", "NFS-3M", "NFS-3M"],
    "Index":["F1A", "F1A", "F2L", "F2L", "F2L", "F2L", "F3I_PO1.I1A", "F2L", "F2L", "F2L", "F2L", "F2L", "F2L", "F1A", "F1A", "F2L", "F2L", "F2L", "F1A", "F3I_PO1.I1", "F1A", "F1A", "F2L"],
    "Group":["b", "a", "b", "b", "b", "b", "a", "b", "b", "b", "b", "b", "b", "b", "b", "a", "a", "a", "a", "d", "b", "b", "b"],
    "Caption":["xxx", "dfasd", "bbbbb", "wewer", "qewqe", "uytuy", "sdf", "tu56r", "Other", "wer42", "eryru", "wetweryt", "eqwwqeqwq", "f", "asdfsad", "f", "asdfsad", "Others", "fa", "a", "sdf", "asdfsad", "qwewe"],
    "Normal balance side":["D", "D", "C", "C", "C", "C", "D", "C", "C", "C", "C", "C", "C", "D", "D", "C", "C", "C", "D", "C", "C", "C", "C"],
    "Separate CY":["-99", "53", "-87", "20", "0", "0", "47", "0", "33", "90", "-30", "33", "20", "2", "27", "38", "-1", "-100", "5", "69", "3", "-58", "20"],
    "Separate PY":["10", "84", "-9", "20", "20", "20", "6", "20", "1", "0", "-9", "1", "20", "70", "96", "4", "-54", "-50", "1", "55", "93", "-75", "10"]
})

# 预处理:转换数值列类型,保留原始索引用于同值排序
df['Separate CY'] = df['Separate CY'].astype(int)
df['Separate PY'] = df['Separate PY'].astype(int)
df['original_idx'] = df.index

# 构造Caption排序辅助列:普通内容<Other<Others
def get_caption_rank(cap):
    if cap == 'Other':
        return 2
    elif cap == 'Others':
        return 3
    else:
        return 1
df['caption_rank'] = df['Caption'].apply(get_caption_rank)

# 构造数值排序辅助列:区分数值段优先级、适配排序方向
def get_sort_key(row):
    cy = row['Separate CY']
    py = row['Separate PY']
    side = row['Normal balance side']
    if side == 'D':
        # D类按数值从大到小排序,取负数实现升序等价降序
        cy_key = -cy
        py_key = -py
        # 数值段优先级:正常值(正) > 0 > 相反值(负)
        seg_rank = 1 if cy > 0 else 2 if cy == 0 else 3
    else:
        # C类按数值从小到大排序,直接取原值
        cy_key = cy
        py_key = py
        # 数值段优先级:正常值(负) > 0 > 相反值(正)
        seg_rank = 1 if cy < 0 else 2 if cy == 0 else 3
    return pd.Series([seg_rank, cy_key, py_key])

df[['seg_rank', 'cy_key', 'py_key']] = df.apply(get_sort_key, axis=1)

# 按规则优先级排序
df_sorted = df.sort_values(
    by=['Ref', 'Index', 'Group', 'caption_rank', 'seg_rank', 'cy_key', 'py_key', 'original_idx'],
    ascending=[True]*8
).drop(columns=['original_idx', 'caption_rank', 'seg_rank', 'cy_key', 'py_key']).reset_index(drop=True)

# 输出排序结果
print(df_sorted)

运行上述代码得到的结果与你给出的预期排序结果完全一致。

内容的提问来源于stack exchange,提问作者Thirasak Phromphimon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 14:18:05