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

如何正确对非整数类型numpy数组按指定列进行降序排序

问题原因
  • 调用np.array(data)创建数组时,由于原始数据混合了字符串、数值,还包含unknown文本,numpy自动将整个数组设置为字符串类型,所有数值都被转为字符串格式
  • 排序时按字符串字典序而非数值大小比较,例如字符串'10'首字符为'1',字典序小于'2'的首字符'2',因此数值大于9的元素排序逻辑失效
  • 现有排序逻辑顺序错误:先按月份升序,再对年份做降序稳定排序,无法实现「先按第二列(年份)降序、同一年份再按第三列(月份)降序」的需求
修复方案

单独提取需要排序的年份、月份列转为整数类型,使用numpy的lexsort做多键排序即可一步实现需求,同时修正布尔列的判断逻辑错误,完整可运行代码如下:

import numpy as np
data = [
    ['Other Theft', 2003, 5, 12, 16, 15, 'Strathcona', 49.269802, -123.083763],
    ['Other Theft', 2003, 5, 7, 15, 20, 'Strathcona', 49.269802, -123.083763],
    ['Other Theft', 2003, 4, 23, 16, 40, 'Strathcona', 49.269802, -123.083763],
    ['Other Theft', 2003, 4, 20, 11, 15, 'Strathcona', 49.269802, -123.083763],
    ['Other Theft', 2003, 4, 12, 17, 45, 'Strathcona', 49.269802, -123.083763],
    ['Other Theft', 2003, 3, 26, 20, 45, 'Strathcona', 49.269802, -123.083763],
    ['Offence Against a Person', 2015, 8, 11,'unknown', 'unknown', 'unknown', 0.000000, 0.000000],
    ['Break and Enter Residential/Other', 2003, 3, 10, 12, 0, 'Kerrisdale', 49.228051, -123.146610],
    ['Mischief', 2003, 6, 28, 4, 13, 'Dunbar-Southlands', 49.255559, -123.193725],
    ['Mischief', 2017, 3, 26, 23, 0, 'Sunset', 49.21431483, -123.101945],
    ['Other Theft', 2003, 2, 16, 9, 2, 'Strathcona', 49.269802, -123.083763],
    ['Break and Enter Residential/Other', 2003, 7, 9, 18, 15, 'Grandview-Woodland', 49.267734, -123.067654],
    ['Other Theft', 2003, 1, 31, 19, 45, 'Strathcona', 49.269802, -123.083763],
    ['Mischief', 2003, 9, 27, 1, 0, 'Dunbar-Southlands', 49.253762, -123.194407],
    ['Offence Against a Person', 2017, 1 , 24, 'unknown', 'unknown', 'unknown', 0.000000, 0.000000],
    ['Break and Enter Residential/Other', 2003, 4, 19, 18, 0, 'Grandview-Woodland', 49.267814, -123.067441],
    ['Break and Enter Residential/Other', 2003, 9, 24, 18, 30, 'Grandview-Woodland', 49.267731, -123.067302],
    ['Break and Enter Residential/Other', 2003, 11, 5, 8, 12, 'Sunset', 49.226430, -123.085283],
    ['Break and Enter Commercial', 2003, 9, 26, 2, 30, 'West End', 49.284715, -123.122824],
    ['Break and Enter Residential/Other', 2003, 10, 21, 10, 0, 'Grandview-Woodland', 49.267811, -123.067089],
    ['Other Theft', 2003, 1, 25, 12, 30, 'Strathcona', 49.269802, -123.083763],
    ['Offence Against a Person', 2003, 2, 12, 'unknown', 'unknown', 'unknown', 0.000000, 0.000000],
    ['Other Theft', 2003, 1, 9, 6, 45, 'Strathcona', 49.269802, -123.083763],
    ['Offence Against a Person', 2008, 2, 6, 'unknown', 'unknown', 'unknown', 0.000000, 0.000000],
]
np_array = np.array(data)
bool_column = np.int_(np.empty(np_array.shape[0]))
for line in range(np_array.shape[0]):
    # 修正布尔列判断逻辑:任意列为unknown则标记为0
    if np_array[line,4] == 'unknown' or np_array[line,5] == 'unknown':
        bool_column[line] = int(0)
    else:
        bool_column[line] = 1
np_array = np.append(np_array, np.reshape(bool_column,(np_array.shape[0],-1)), axis=1) 

# 修正排序逻辑:提取年、月转为整数,用lexsort实现多键降序
years = np_array[:, 1].astype(int)
months = np_array[:, 2].astype(int)
# lexsort优先级:最后传入的键优先排序,加负号实现降序,即先按年份降序,再按月份降序
sort_idx = np.lexsort((-months, -years))
np_array = np_array[sort_idx]

# 计算列宽用于格式化输出
equals_spaces = []
temp_for_cicle = 0
for num_in_line in range(np_array.shape[1]):
    for line in range (np_array.shape[0]):
        if len(np_array[line][num_in_line]) > temp_for_cicle:
            temp_for_cicle = len(np_array[line][num_in_line])
    equals_spaces.append(temp_for_cicle)
    temp_for_cicle = 0

# 格式化输出
for line in range(np_array.shape[0]):
    for num_in_line in range (np_array.shape[1]):
        print('{:<{}}'.format(np_array[line][num_in_line],equals_spaces[num_in_line]), end='')
        if num_in_line+1 == np_array.shape[1]:
            print("")
        else:
            print(" | ", end='')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:15:01