我是靠谱客的博主 帅气诺言,最近开发中收集的这篇文章主要介绍【Python】Numpy排序函数详解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 简介
    • quicksort
    • 堆排序
    • 归并排序

简介

np.sort是最常用的排序函数,其输入参数中,axis可以指定排序的坐标轴,其最常用的使用方法如下

>>> x = np.random.rand(2,4)
>>> x
array([[0.92849373, 0.18556701, 0.47361308, 0.63378477],
       [0.25428974, 0.94955477, 0.74649189, 0.945536  ]])
>>> np.sort(x, axis=0)
array([[0.25428974, 0.18556701, 0.47361308, 0.63378477],
       [0.92849373, 0.94955477, 0.74649189, 0.945536  ]])
>>> np.sort(x,axis=1)
array([[0.18556701, 0.47361308, 0.63378477, 0.92849373],
       [0.25428974, 0.74649189, 0.945536  , 0.94955477]])

numpy中针对数组排序,实现了多种不同的算法,在sort中,通过kind参数可以选择排序方案

kind速度最坏性能稳定性
'quicksort'1 O ( n 2 ) O(n^2) O(n2)
'heapsort'3
'mergesort'2
'timsort’'2

上表中✅表示 O ( n log ⁡ n ) O(nlog n) O(nlogn)

由于本文主要讲解np.sort的用法,所以下面堆这四种kind做一个简要的说明,而不去深挖其实现的细节。

quicksort

其中,在最新的numpy中,quicksort采用的并不是经典的快排算法,而是改良后的introsort算法。

快排算法大家都非常熟悉了,其简单的Python示意如下

def qSort(arr):
    if len(arr) < 1:
        return arr
    midValue = arr[len(arr)//2]
    L = [x for x in arr if  x < midValue]
    M = [x for x in arr if x == midValue]
    R  = [x for x in arr if x > midValue]
    return qSort(L) + M + qSort(R)

print(qSort([3,34,56,7,89,2,4]))

由于不断地二分,使得迭代次数从经典插入的 n n n次下降为 log ⁡ 2 N log_2N log2N次,突破了 n 2 n^2 n2的限制,从而获得了快排的美名。

但从上面的代码也可以看到,首先,当元素个数较少时,快排是体现不出性能的;其次,当元素个数较多时,会产生非常深的递归,造成较大的内存开销。

introSort针对快排的这两个弱点,做了如下优化

  1. 当递归到某一深度,arr的元素个数较少时,采取插入排序
  2. 当递归的层次过深,则更改排序策略,使用堆排序

堆排序

堆排序是建立在最大堆或者最小堆这种数据结构之上的,所谓最小堆,本质是一个完全二叉树,要求父节点不大于其所有子节点。

最小堆的完全二叉树结构,决定了树高在 log ⁡ 2 ( n + 1 ) log_2(n+1) log2(n+1)的水平,从而使得自上而下遍历最大堆的时间复杂度降低到 log ⁡ 2 ( n + 1 ) log_2(n+1) log2(n+1)

在这里插入图片描述

根据上图可知,若父节点的序号为 n n n,则左子节点序号为 2 n + 1 2n+1 2n+1,右子节点序号为 2 n + 2 2n+2 2n+2

可以将上图理解为一个排好序的最小堆,如果1位变成15,那么这个节点将违反最小堆的原则,经过比对,应该调换15和3的位置。调换之后,15仍然比7和8大,则继续调换15和7的位置,则这个最小堆变为

在这里插入图片描述

归并排序

归并排序是算法导论中介绍的第一种使用分治策略的排序算法,基本思路是将数组拆分成子数组,然后令子数组有序,再令数组之间有序,则可以使整个数组有序。其算法步骤如下:

设数组有 n n n个元素, { a 0 , a 1 , … , a n } {a_0,a_1,ldots,a_n} {a0,a1,,an}

  1. 如果数组元素大于2,则将数组分成左数组和右数组,否则将数组转成有序数组
  2. 对左数组和右数组执行1操作。
  3. 合并左数组和右数组。

TimSortintroSort相似,都是缝合得比较厉害的排序算法,其中introSort是C++标准库中的快排方案,而TimSort则是Tim Peters于2002年首先应用在Python的。

timsort的基本思路是最大限度地利用数组中已经存在的有序子数组,Tim将这些已经有序的子数组称为run,排序过程中,像归并排序一样,不断地将迭代元素放入每个run中,同时对不同的run进行合并,直到只剩下一个run

最后

以上就是帅气诺言为你收集整理的【Python】Numpy排序函数详解的全部内容,希望文章能够帮你解决【Python】Numpy排序函数详解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部