NumPy 数组排序:综合指南

2023-10-16

在本教程中,我们将讨论如何对NumPy 数组使用不同的技术。

接下来,我们将了解如何按升序和降序对 NumPy 数组进行排序,以及如何处理多维数组、就地排序、间接排序以及排序时遇到的常见问题。

 

 

使用 np.sort() 对 NumPy 数组进行排序

我们可以使用以下方法对给定数组进行排序np.sort()功能。默认情况下,该函数按升序对数组进行排序。


import numpy as np
arr = np.array([6, 4, 8, 1, 3])
sorted_arr = np.sort(arr)
print("Sorted Array:", sorted_arr)
  

Output:


Sorted Array: [1 3 4 6 8]
  

这里我们使用了np.sort(),它按升序对 NumPy 数组进行排序。我们将原始数组作为参数传递,它返回数组的排序副本,而不修改原始数组。

 

按降序对 NumPy 进行排序

要按降序(从最大到最小)对 NumPy 数组进行排序,我们仍将使用np.sort(),但我们将颠倒已排序数组的顺序。


descending_arr = np.sort(arr)[::-1]
print("Array in Descending Order:", descending_arr)
  

Output:


Array in Descending Order: [8 6 4 3 1]
  

在这里,我们使用了切片技术[::-1]反转已排序的数组。这将按降序返回数组。

 

按多列排序(结构化数组)

要按多列对 NumPy 结构化数组进行排序,可以将要排序的列名称传递给order的参数numpy.sort()功能:


import numpy as np
data_type = np.dtype([('name', 'S15'), ('age', 'i4'), ('height', 'f4')])
data = np.array([('John', 20, 170.1),
                 ('Doe', 20, 180.8),
                 ('Alice', 22, 155.3),
                 ('Bob', 22, 175.2),
                 ('Charlie', 23, 165.7)],
                dtype=data_type)
data_sorted = np.sort(data, order=['age', 'height'])
print(data_sorted)
  

Output:


[(b'John', 20, 170.1)
(b'Doe', 20, 180.8)
(b'Alice', 22, 155.3)
(b'Bob', 22, 175.2)
(b'Charlie', 23, 165.7)]  

在此示例中,我们有一个包含三个字段的 NumPy 结构化数组 - “name”、“age”和“height”。我们首先按“年龄”排序,然后按“身高”排序。

这意味着,如果有两个人年龄相同,则较短的将排在第一位。

要按多列对 2D(或更高)数组进行排序,您可以使用lexsort()正如我们将在本教程后面看到的。

 

沿轴排序(多维数组)

对于多维非结构化数组,我们可以指定对元素进行排序的轴。

对 2D NumPy 数组进行排序


# Create a 2-dimensional array
arr_2d = np.array([[2, 3, 1], [5, 0, 4]])
print("Original 2D Array:n", arr_2d)

# Sort along the first axis
sorted_arr_2d_axis0 = np.sort(arr_2d, axis=0)
print("Array sorted along the first axis:n", sorted_arr_2d_axis0)
  

Output:


Original 2D Array:
 [[2 3 1]
 [5 0 4]]
Array sorted along the first axis:
 [[2 0 1]
 [5 3 4]]
  

在这段代码中,我们首先创建了一个二维数组。为了沿第一个轴(即沿列)对该数组进行排序,我们使用了np.sort()功能与axis=0.

这将分别重新排列数组每列中的元素,从最小到最大排序。

对 3D NumPy 数组进行排序

对 3 维(或 n 维)数组进行排序涉及与对 2D 数组进行排序相同的原理。您只需指定要排序的轴即可。


# Create a 3-dimensional array
arr_3d = np.array([[[3, 2, 1], [6, 5, 4]], [[9, 8, 7], [12, 11, 10]]])
print("Original 3D Array:n", arr_3d)

# Sort along the last axis
sorted_arr_3d = np.sort(arr_3d, axis=-1)
print("3D Array sorted along the last axis:n", sorted_arr_3d)
  

Output:


Original 3D Array:
 [[[ 3  2  1]
  [ 6  5  4]]
 [[ 9  8  7]
  [12 11 10]]]
3D Array sorted along the last axis:
 [[[ 1  2  3]
  [ 4  5  6]]
 [[ 7  8  9]
  [10 11 12]]]
  

在此代码中,我们首先创建了一个 3D 数组。为了沿最后一个轴(即 axis=-1)对该数组进行排序,我们使用了np.sort()功能与axis=-1。因此,每个一维子数组都是独立排序的。

 

排序算法

np.sort()默认情况下使用快速排序算法,但您可以使用以下命令选择不同的排序算法kind范围。可用的算法包括“快速排序”、“合并排序”、“堆排序”和“稳定”。

 

快速排序(最快)

您可以使用kind参数来指定快速排序算法像这样:


sorted_arr = np.sort(arr, kind='quicksort')
print("Array sorted using quicksort:", sorted_arr)
  

Output:


Array sorted using quicksort: [1 3 4 6 8]
  

归并排序

合并排序是 NumPy 中提供的另一种排序算法,以其可预测的 O(n log n) 时间复杂度而闻名。


sorted_arr = np.sort(arr, kind='mergesort')
print("Array sorted using mergesort:", sorted_arr)
  

Output:


Array sorted using mergesort: [1 3 4 6 8]
  

堆排序(最慢)

堆排序是一种基于比较的排序算法,时间复杂度为 O(n log n)。


sorted_arr = np.sort(arr, kind='heapsort')
print("Array sorted using heapsort:", sorted_arr)
  

Output:


Array sorted using heapsort: [1 3 4 6 8]
  

稳定排序

“稳定”算法使相等的元素保持与原始数组中相同的顺序。该算法基于基数排序或合并排序,具体取决于数据类型。


sorted_arr = np.sort(arr, kind='stable')
print("Array sorted using stable sort:", sorted_arr)
  

Output:


Array sorted using stable sort: [1 3 4 6 8]
  

 

何时使用每种算法?

为 NumPy 数组选择正确的排序算法可以极大地影响代码的效率。以下是选择正确算法的一般指南:

  • 快速排序: 这往往是最快的算法对于数值数据。如果您需要对大型数组进行排序,并且不需要担心最坏情况或稳定性,那么这是一个不错的选择。但是,请记住,快速排序最坏情况的时间复杂度为 O(n^2)。
  • 归并排序:如果您需要稳定的排序(即保留相等元素的顺序),合并排序是一个不错的选择。它的时间复杂度始终为 O(n log n),但是需要额外的内存,这对于大型阵列可能是一个问题。
  • Heapsort: 如果内存是一个问题,堆排序是一个不错的选择,时间复杂度为 O(n log n)。然而,它并不稳定。
  • 稳定排序:如果您需要稳定的排序并且内存不是问题,或者您是处理非数字数据,稳定排序算法是一个不错的选择。

 

使用 np.ndarray.sort() 进行就地排序

如果要对原始数组进行排序而不创建副本,可以使用sort()的方法ndarray目的。这执行就地排序。


# Original array
arr = np.array([4, 3, 1, 6, 8])
print("Original Array:", arr)

# In-place sort
arr.sort()
print("Sorted Array:", arr)
  

Output:


Original Array: [4 3 1 6 8]
Sorted Array: [1 3 4 6 8]
  

在这段代码中,我们调用了sort()NumPy 数组对象上的方法,该方法对数组进行就地排序。不像np.sort()它修改了原始数组。

 

间接排序:argsort 和 lexsort

间接排序,例如argsort() and lexsort(),不对数组的值进行排序,而是返回一个索引数组,如果将其应用于该数组,将产生一个已排序的数组。

argsort


# Using argsort
sorted_indices = np.argsort(arr)
print("Sorted Indices:", sorted_indices)

# Apply the sorted indices to arr
sorted_arr = arr[sorted_indices]
print("Sorted Array:", sorted_arr)
  

Output:


Sorted Indices: [2 1 0 3 4]
Sorted Array: [1 3 4 6 8]
  

Here, np.argsort()返回一个索引数组,用于对数组进行排序。然后我们将这些索引应用于数组以获得排序后的数组。

lexsort(按多列对非结构化数组进行排序)

假设我们想要根据第一列中的值对二维数组进行排序,然后根据第二列中的值进行排序。

我们可以使用np.lexsort()函数,它对多个键执行间接排序。


# Create a 2-dimensional array
arr_2d = np.array([[2, 3], [1, 5], [1, 4], [2, 2]])
print("Original 2D Array:n", arr_2d)

# Sequence of keys
keys = (arr_2d[:, 1], arr_2d[:, 0]) 

# Indices for sorted array
sorted_indices = np.lexsort(keys)

# Apply array indexing to obtain sorted array
sorted_arr_2d = arr_2d[sorted_indices]
print("Array sorted by multiple columns:n", sorted_arr_2d)
  

Output:


Original 2D Array:
 [[2 3]
 [1 5]
 [1 4]
 [2 2]]
Array sorted by multiple columns:
 [[1 4]
 [1 5]
 [2 2]
 [2 3]]
  

在此代码中,我们创建了一个 2D 数组,然后创建了一个键序列,我们要根据该序列对数组进行排序。我们用了np.lexsort()获取可用于生成排序数组的索引数组。

最后,我们应用数组索引来获得排序后的数组。

 

衡量绩效

根据经验测量不同排序算法的性能非常重要,尤其是在处理较大的数据集时。

这是我编写的一个小脚本,用于测量每个排序算法在大小为 1 亿的大型随机数组上的执行时间:


import numpy as np
import time

# Create a large numpy array
large_arr = np.random.randint(0, high=1000000, size=100000000)

algorithms = ['quicksort', 'mergesort', 'heapsort', 'stable']
for algorithm in algorithms:
    start = time.time()
    np.sort(large_arr, kind=algorithm)
    end = time.time()
    print(f"{algorithm.capitalize()} Time: {end - start} seconds")

# Test the in-place sort
start = time.time()
arr_copy = np.copy(large_arr)
arr_copy.sort()  # Uses quicksort by default
end = time.time()
print(f"In-place sort Time: {end - start} seconds")
  

Output:


Quicksort Time: 14.426326036453247 seconds
Mergesort Time: 18.75661039352417 seconds
Heapsort Time: 47.7882182598114 seconds
Stable Time: 18.685729265213013 seconds
In-place sort Time: 14.05978536605835 seconds
  

这些结果将根据系统的特定硬件和软件配置而有所不同。但一般来说,正如预期的那样,快速排序对于数值数据来说往往是最快的。

 

常见问题及解决方法

对 NumPy 数组进行排序时可能存在几个问题和注意事项:

对不同数据类型的 NumPy 数组进行排序:NumPy 数组可以包含不同的数据类型,这可能会导致排序时出现问题。

解决方案是确保数组只包含一种数据类型,或者将其转换为可以排序的类型。

例如,如果您有一个字符串和整数的数组,则可以在排序之前将整数转换为字符串。


# An array with different data types
arr = np.array(['banana', 2, 'apple'])
print("Original array:", arr)

# Convert all elements to strings
arr = arr.astype(str)
print("Converted array:", arr)

# Now we can sort the array
print("Sorted array:", np.sort(arr))
  

Output:


Original array: ['banana' '2' 'apple']
Converted array: ['banana' '2' 'apple']
Sorted array: ['2' 'apple' 'banana']
  

对缺失值 (NaN) 的数组进行排序:NumPy 认为 NaN(非数字)大于任何其他值,这可能会导致意外的排序结果。

您可能希望在排序之前处理 NaN 值(例如,通过替换或删除它们)。

大型数组的内存使用情况:大数组会消耗大量内存。在这些情况下,您可能需要使用就地排序。

 

进一步阅读

https://numpy.org/doc/stable/reference/ generated/numpy.sort.html

https://numpy.org/doc/stable/reference/ generated/numpy.ndarray.sort.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NumPy 数组排序:综合指南 的相关文章

随机推荐

  • 如何在 Ubuntu 18.04 上添加交换空间

    交换空间是磁盘上的空间 当物理 RAM 内存已满时使用 当 Linux 系统耗尽 RAM 时 非活动页面将从 RAM 移至交换空间 交换空间可以采用专用交换分区或交换文件的形式 通常 在虚拟机上运行 Ubuntu 时 不存在交换分区 唯一的
  • Linux 中的终止命令

    Linux是一个伟大而先进的操作系统 但它并不完美 有时 某些应用程序可能会开始表现不稳定并变得无响应或开始消耗大量系统资源 无响应的应用程序无法重新启动 因为原始应用程序进程永远不会完全关闭 唯一的解决方案是重新启动系统或终止应用程序进程
  • 如何更改 Linux 中的 Swappiness 值

    交换空间是 RAM 内存已满时使用的硬盘的一部分 交换空间可以是专用交换分区或交换文件 当 Linux 系统耗尽物理内存时 非活动页面将从 RAM 移至交换空间 Swappiness 是一个 Linux 内核属性 它设置将页面从物理内存换出
  • 如何在 Python 中查找列表的长度

    列表是Python中最常用的数据类型之一 用于存储相同类型的项目的集合 本文介绍如何查找列表的长度 len 功能 Python有一个内置函数len 返回给定对象的长度 该对象可以是一个list 元组 字符串 字典等 的语法len 函数如下
  • Tmux 入门

    本指南将介绍 Tmux 的安装和基本用法 以帮助您入门和运行 什么是 tmux Tmux 是终端多路复用器的替代品GNU 屏幕 换句话说 这意味着您可以启动 Tmux 会话 然后在该会话中打开多个窗口 每个窗口占据整个屏幕 并且可以分割成矩
  • 如何在 Python 中向列表添加元素(追加、扩展和插入)

    在 Python 中使用列表时 您经常需要向列表中添加新元素 Python 列表数据类型具有三种添加元素的方法 append 将单个元素追加到列表中 extend 将可迭代的元素追加到列表中 insert 在列表的给定位置插入单个项目 所有
  • 如何添加 Git 远程

    通常 在使用 Git 时 您将仅使用一个名为 origin 的远程服务器 并针对不同的功能和环境使用不同的分支 Origin 是克隆存储库时自动创建的远程名称 并指向克隆的存储库 然而 当与一群人协作处理一个项目时 您可能会发现使用多个 G
  • Linux 中的 Dig 命令(DNS 查找)

    Dig Domain Information Groper 是一个强大的命令行工具 用于查询 DNS 名称服务器 The dig命令 允许您查询有关各种 DNS 记录的信息 包括主机地址 邮件交换和名称服务器 由于其灵活性和易用性 它是系统
  • 如何在 Ubuntu 20.04 上安装 Zoom

    Zoom是一个易于使用的通信平台 集云视频会议 实时消息传递和内容共享于一体 使用 Zoom 您可以举办网络研讨会 组织在线会议以及创建会议室 本指南介绍如何在 Ubuntu 20 04 上安装 Zoom 相同的说明适用于所有基于 Debi
  • 如何在 Ubuntu 20.04 上安装 Memcached

    Memcached 是一个免费开源的高性能内存键值数据存储 它通常用于通过缓存 API 和数据库调用结果中的各种对象来加速应用程序 本文介绍如何在 Ubuntu 20 04 上安装和配置 Memcached 安装 Memcached mem
  • PyQt5绘图教程(绘画API)

    在本教程中 我们将学习如何绘制矢量图形PyQt5 正如您将看到的 在 Python 中 PyQt5 模块是可用于绘图目的的最简单的模块 在开始之前 让我们使用 PyQt5 创建一个窗口 在其中绘制图形 目录 hide 1 创建一个 PyQt
  • NumPy where 教程(带示例)

    The numpy where函数用于检索 ndarray 中给定条件为 true 的元素的索引 学完本教程后 您将充分了解如何使用numpy where查询NumPy 数组 目录 hide 1 语法和参数 2 使用 x 和 y 参数替换值
  • 使用 sed 命令掌握 Linux 文件中的文本插入

    The ised 中的命令用于在行前插入文本 的一般语法为i命令是 sed pattern i text to be inserted filename 在本教程中 我们将重点介绍如何使用sed命令 目录 hide 1 Sed Insert
  • Sed 命令指南:Linux 中的文本编辑

    sed代表流编辑器 该命令允许您解析和转换文本数据 如果输入源自文件 管道或标准输入 sed逐行处理它 With sed 您可以执行各种文本操作 如插入 删除 搜索和替换 目录 hide 1 Basic Syntax and Operati
  • Pandas查询方法:高效过滤DataFrame

    Pandas提供query 允许用户使用字符串表达式查询 DataFrame 的方法 在本教程中 您将了解query方法以及如何在实际应用中使用它 目录 hide 1 Pandas 查询语法和参数 2 使用查询方法过滤数据帧 3 Using
  • 用于网络故障排除的 Linux 网络命令

    在上一篇文章中 我们谈到了Linux进程管理t 在这篇文章中 我们将讨论 Linux 网络命令以及如何排除网络故障 如果确保物理网络正常工作 下一步就是对网络进行故障排除 这里我们进入我们的主题 即 Linux 网络命令以及如何使用它们对网
  • Pandas loc 与 iloc:何时使用它们进行数据选择

    The loc and iloc属性是 Pandas 库的一部分 允许根据某些标准从 DataFrame 中选择数据 本教程将讨论这两种属性之间的主要区别 以及如何确保您使用适合您特定需求的属性 下表总结了这两个属性之间的差异 Proper
  • 使用 PHP 将数组转换或转换为对象(Hydrator 模式)

    在这篇文章中 我们将使用 PHP Hydrator 模式将数组转换为对象 这个方法很简单 就是将数据从一个地方传输到另一个地方 我们将定义一个类 它将一个数组和一个对象作为输入 并搜索对象中的所有 set 方法 并用数组中的值填充它 首先
  • 使用 Linux 进程管理命令进行性能调优

    在服务器管理中 了解正在运行的进程如何详细工作 从高负载进程到慢响应时间进程 非常重要 当你的服务器变得如此缓慢或无法响应时 你应该了解进程管理或Linux进程管理 当是时候杀死一个进程 or renice它以及如何monitor当前正在运
  • NumPy 数组排序:综合指南

    在本教程中 我们将讨论如何对NumPy 数组使用不同的技术 接下来 我们将了解如何按升序和降序对 NumPy 数组进行排序 以及如何处理多维数组 就地排序 间接排序以及排序时遇到的常见问题 目录 hide 1 使用 np sort 对 Nu