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

np.lexsort如何为每个排序列单独指定升降序(支持字符串列场景)

Numpy多列排序自定义每列升降序的实现方法

numpy的np.lexsort本身仅支持所有排序键按升序排列,要实现自定义每列升降序,核心逻辑是:对需要降序排列的列,将其转换为升序排列等价于原列降序排列的键,再传入lexsort即可。

示例场景直接解法

你的示例数组所有元素为字符串类型,排序键为数值内容,直接转整数取负即可作为降序的键:

import numpy as np
arr = np.array([list("aaabbb"),[1,2,3,1,4,3],[1,2,3,4,6,6]]).T

# 按列2(索引2)优先降序,再按列1(索引1)降序
idx = np.lexsort([
    -arr[:,1].astype(int), # 第二排序规则:列1降序
    -arr[:,2].astype(int)  # 第一排序规则:列2降序
])
sorted_arr = arr[idx]

运行后得到的结果和你给出的预期完全一致。

通用实现方案

如果要支持任意数据类型(含字符串、数值等所有支持比较的类型)、自由指定排序列和每个列的升降序,可以封装为通用函数:

def numpy_multi_sort(arr, sort_cols, ascending):
    """
    通用numpy多列自定义排序函数
    :param arr: 输入numpy数组
    :param sort_cols: 排序列索引列表,优先级从低到高(和lexsort参数顺序一致)
    :param ascending: 布尔列表,和sort_cols长度一一对应,True为升序,False为降序
    :return: 排序后的数组
    """
    sort_keys = []
    for col_idx, is_asc in zip(sort_cols, ascending):
        col_data = arr[:, col_idx]
        # 生成列的全局排名,兼容所有可比较类型
        col_rank = np.argsort(np.argsort(col_data))
        # 降序则对排名取负,lexsort升序排列负排名等价于原列降序
        if not is_asc:
            col_rank = -col_rank
        sort_keys.append(col_rank)
    # 获取排序索引
    sort_idx = np.lexsort(sort_keys)
    return arr[sort_idx]

如果你习惯pandas的调用风格(排序列表靠前的优先级更高),可以再加一层适配:

def numpy_multi_sort_pd(arr, by_cols, ascending):
    """
    对齐pandas sort_values调用风格的多列排序
    :param arr: 输入numpy数组
    :param by_cols: 排序列索引列表,优先级从高到低(和pandas by参数一致)
    :param ascending: 布尔列表,和by_cols长度一一对应,True为升序,False为降序
    :return: 排序后的数组
    """
    # 反转顺序适配lexsort的优先级规则
    return numpy_multi_sort(arr, by_cols[::-1], ascending[::-1])

调用示例

# 对应你的需求:优先按列2降序,再按列1降序
sorted_arr = numpy_multi_sort_pd(arr, by_cols=[2, 1], ascending=[False, False])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 02:33:01