如何在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
相关产品推荐
相关产品推荐

