Numpy 如何让 argsort 两个相等的值排序

一、场景

       遇到多个数组排序后存在相同元素的情况,如何让这些相同元素在排序结果中更加随机地分布,如何稳定排序,是一个不容易解决的问题,

二、numpy.argsort

       在NumPy中,numpy.argsort函数用于返回输入数组中元素排序后的索引数组,而不是直接对元素进行排序,在不改变原数组的基础上,实现了灵活的数据排序与索引操作。与numpy.sort直接返回排序后数组不同,argsort更加适用于需要原地排序或者基于排序进行其他操作的场景。

numpy.argsort(a, axis=-1, kind='quicksort', order=None)

"""参数详解
a:待排序的数组。
axis(可选):沿着哪个轴进行排序,默认为-1,即最后一个轴。对于一维数组,此参数无效。
kind(可选):排序算法的类型,默认为’quicksort’。还可以选择’mergesort’、'heapsort’等,
             不同算法在效率和稳定性上有差异。
order(可选):当数组是结构化数组或记录数组时,可以按照字段名进行排序。
"""


import numpy as np

# 创建包含相同元素的数组
arr = np.array([3, 1, 2, 1, 3, 2, 3, 1, 1])
# 对数组进行排序并打印结果
sorted_indices = np.argsort(arr)
print("排序前的数组:", arr)
print("排序后的下标数组:", sorted_indices)
"""
排序前的数组: [3 1 2 1 3 2 3 1 1]
排序后的下标数组: [1 3 7 8 2 5 0 4 6]
"""

x=np.array([2,6,3,8,9,-1])
#直接使用的两种形式
y=x.argsort()
z=np.argsort(x)

三、随机排序 

        一种解决方法是通过对排序后的下标数组进行迭代,找到相同元素以及它们的下标,然后将它们随机排列。

# 定义一个辅助函数,用于得到相同值的下标进行随机化处理
def randomize_same_value_indices(sorted_indices):
    sorted_values = arr[sorted_indices]
    indices_groups = np.split(sorted_indices, np.cumsum(np.unique(sorted_values, return_counts=True)[1])[:-1])
    for group in indices_groups:
        if group.size > 1:
            np.random.shuffle(group)
    return np.concatenate(indices_groups)

# 对数组进行排序并随机处理相同元素
sorted_indices = randomize_same_value_indices(np.argsort(arr))
print("排序前的数组:", arr)
print("排序后的下标数组:", sorted_indices)
"""
排序前的数组: [3 1 2 1 3 2 3 1 1]
排序后的下标数组: [8 3 7 1 2 5 4 6 0]
"""

四、稳定排序

  • 逆序排序:要得到降序排列的索引,可以简单地对升序索引进行反向排序,即[::-1]操作。
  • 稳定性:对于需要稳定排序的应用场景(即相同元素的相对位置不变),可以选择’mergesort’算法。
  • 性能考量:虽然快速排序(quicksort)通常较快,但在数组元素分布极不均匀时,mergesort或heapsort可能是更好的选择。
import numpy as np

# 创建包含相同元素的数组
arr = np.array([3, 1, 2, 1, 3, 2, 3, 1, 1])

# 对数组进行排序并打印结果
sorted_indices = np.argsort(arr, kind='mergesort')
sorted_indices2 = np.argsort(-arr, kind='mergesort')
print("排序前的数组:", arr)
print("排序后的下标数组:", sorted_indices)

"""
排序前的数组: [3 1 2 1 3 2 3 1 1]
排序后的下标数组: [1 3 7 8 2 5 0 4 6]
"""

 

 五、多维数组排序

import numpy as np
 
arr = np.array([[5, 2, 3],
[4, 1, 6],
[7, 8, 9]])
#索引数组
ndx = np.argsort(arr,axis=1)
#排序后的数组
sorted_arr = np.take_along_axis(arr, ndx, axis=1)#axis=1是按行排序,axis=0是按列排序
 
#打印
print(ndx)
print(sorted_arr)

六、结构化数组排序

import numpy as np
 
dt = np.dtype([('name', 'S10'), ('age', int)])
data = np.array([('Alice', 24), ('Bob', 19), ('Charlie', 33)],
               dtype=dt)
# 按'age'字段排序
age_indices = np.argsort(data, order='age')
print(age_indices)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

**星光*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值