排序、搜索和计数函数
NumPy - 排序、搜索和计数函数
Section titled “NumPy - 排序、搜索和计数函数”NumPy 提供了一系列高效的函数用于数组排序、元素搜索和出现次数计数。
NumPy 提供了几种排序算法 (quicksort 快速排序, mergesort 归并排序, heapsort 堆排序, stable 稳定排序)。选择不同的算法会影响性能和 稳定性 (stable)(即相等元素的相对顺序是否保持不变)。
类型 (kind) | 平均速度 | 最差情况 | 工作空间 | 稳定性 (Stable) |
|---|---|---|---|---|
| ‘quicksort’ (默认) | 最快 | O(n^2) | 常量 | 否 |
| ’mergesort’ | 中等 | O(n*log(n)) | ~n/2 | 是 |
| ’heapsort’ | 最慢 | O(n*log(n)) | 常量 | 否 |
| ’stable’ | 中等 | O(n*log(n)) | ~n/2 | 是 (适配 mergesort/timsort) |
注意: 当需要保留相等元素的原始顺序时,‘stable’ 通常是一个不错的选择。
numpy.sort()
Section titled “numpy.sort()”返回数组的 排序副本。它不会修改原始数组。
numpy.sort(a, axis=-1, kind=None, order=None)参数:
| 参数 | 描述 |
|---|---|
| a | 待排序的输入数组。 |
| axis | 沿哪个轴进行排序。默认是 -1 (最后一个轴)。如果为 None,则在排序前将数组 展平 (flatten)。 |
| kind | 排序算法 (‘quicksort’, ‘mergesort’, ‘heapsort’, ‘stable’)。默认取决于 NumPy 版本,通常是 ‘quicksort’。 |
| order | 对于 结构化数组 (structured array),指定按哪个 字段 (field) 进行排序。 |
示例: 使用 np.sort
Section titled “示例: 使用 np.sort”沿不同轴排序二维数组和排序结构化数组。
import numpy as np
# --- 基本排序 ---a = np.array([[3, 7], [9, 1]])
print('Original array:')print(a)
# 沿最后一个轴 (行) 排序 - 默认行为print('\nSorted along axis=-1 (rows):')print(np.sort(a))
# 沿轴 0 (列) 排序print('\nSorted along axis=0 (columns):')print(np.sort(a, axis=0))
# 排序展平后的数组print('\nSorted flattened array:')print(np.sort(a, axis=None))
# --- 结构化数组排序 ---# 定义一个结构化数据类型dt = np.dtype([('name', 'S10'), ('age', int)])people = np.array([('Raju', 21), ('Anil', 25), ('Ravi', 17), ('Amar', 27)], dtype=dt)
print('\n\nOriginal structured array:')print(people)
# 按 'name' 字段排序print('\nSorted by name:')print(np.sort(people, order='name'))
# 按 'age' 字段排序print('\nSorted by age:')print(np.sort(people, order='age'))输出:
Original array:[[3 7] [9 1]]
Sorted along axis=-1 (rows):[[3 7] [1 9]]
Sorted along axis=0 (columns):[[3 1] [9 7]]
Sorted flattened array:[1 3 7 9]
Original structured array:[(b'Raju', 21) (b'Anil', 25) (b'Ravi', 17) (b'Amar', 27)]
Sorted by name:[(b'Amar', 27) (b'Anil', 25) (b'Raju', 21) (b'Ravi', 17)]
Sorted by age:[(b'Ravi', 17) (b'Raju', 21) (b'Anil', 25) (b'Amar', 27)]注意: 要对数组进行 就地排序 (修改原始数组),请使用 ndarray.sort() 方法:a.sort()。
numpy.argsort()
Section titled “numpy.argsort()”执行 间接排序 (indirect sort)。它不返回排序后的数组,而是返回能对原始数组进行排序的 索引。当需要根据一个数组的顺序来排序多个相关数组时,这非常有用。
示例: 使用 argsort
Section titled “示例: 使用 argsort”找到数组的排序索引并用它们重构数组。
import numpy as np
x = np.array([30, 10, 20])
print('Original array:')print(x)
print('\nIndices that would sort x:')indices = np.argsort(x)print(indices)
print('\nReconstruct sorted array using indices:')print(x[indices]) # 使用索引进行 高级索引 (fancy indexing)输出:
Original array:[30 10 20]
Indices that would sort x:[1 2 0]
Reconstruct sorted array using indices:[10 20 30]numpy.lexsort()
Section titled “numpy.lexsort()”使用一系列 键 (key)(数组)执行 间接 稳定排序。它首先根据提供的 最后一个 键进行排序,然后使用倒数第二个键来 打破平局 (break ties),依此类推。返回基于这些键对数据进行排序所需的索引。
示例: 使用 lexsort
Section titled “示例: 使用 lexsort”首先按部门 (‘dv’),然后按姓名 (‘nm’) 对姓名进行排序。
import numpy as np
# 数据数组 (用于排序的键)names = np.array(['Raju', 'Anil', 'Ravi', 'Amar'])divisions = np.array(['f.y.', 's.y.', 's.y.', 'f.y.'])
# 首先按姓名排序,然后按部门排序 (键按后到先的顺序提供)# 因此,主要排序键是 'names',次要排序键是 'divisions'indices = np.lexsort((divisions, names))
print('Indices from lexsort (sort by names, then divisions):')print(indices)
print('\nUse indices to get sorted data:')print([f'{names[i]}, {divisions[i]}' for i in indices])输出:
Indices from lexsort (sort by names, then divisions):[3 1 0 2]
Use indices to get sorted data:['Amar, f.y.', 'Anil, s.y.', 'Raju, f.y.', 'Ravi, s.y.']NumPy 提供了查找最大/最小值或满足特定 条件 (condition) 的元素的函数。
numpy.argmax() 和 numpy.argmin()
Section titled “numpy.argmax() 和 numpy.argmin()”分别返回沿给定轴的最大和最小元素的 索引。如果数组被展平 (axis=None),则返回展平数组中的索引。
示例: 使用 argmax 和 argmin
Section titled “示例: 使用 argmax 和 argmin”import numpy as np
a = np.array([ [30, 40, 70], [80, 20, 10], [50, 90, 60]])
print('Original array:')print(a)
# 最大元素的索引 (展平后)print('\nIndex of max element (flattened):', np.argmax(a))# 最大元素的值print('Value of max element:', a.flat[np.argmax(a)])
# 沿轴 0 (列) 的最大元素索引print('\nIndices of max elements along axis 0 (columns):', np.argmax(a, axis=0))# 沿轴 1 (行) 的最大元素索引print('Indices of max elements along axis 1 (rows):', np.argmax(a, axis=1))
# 最小元素的索引 (展平后)print('\nIndex of min element (flattened):', np.argmin(a))# 最小元素的值print('Value of min element:', a.flat[np.argmin(a)])
# 沿轴 0 (列) 的最小元素索引print('\nIndices of min elements along axis 0 (columns):', np.argmin(a, axis=0))# 沿轴 1 (行) 的最小元素索引print('Indices of min elements along axis 1 (rows):', np.argmin(a, axis=1))输出:
Original array:[[30 40 70] [80 20 10] [50 90 60]]
Index of max element (flattened): 7Value of max element: 90
Indices of max elements along axis 0 (columns): [1 2 0]Indices of max elements along axis 1 (rows): [2 0 1]
Index of min element (flattened): 5Value of min element: 10
Indices of min elements along axis 0 (columns): [0 1 1]Indices of min elements along axis 1 (rows): [0 2 0]numpy.nonzero()
Section titled “numpy.nonzero()”返回 非零 (non-zero) 元素的索引。结果是一个元组 (tuple),其中包含按维度划分的数组,每个数组包含该维度中非零元素的索引。
示例: 使用 nonzero
Section titled “示例: 使用 nonzero”import numpy as np
a = np.array([ [30, 40, 0], [0, 20, 10], [50, 0, 60]])
print('Original array:')print(a)
print('\nIndices of non-zero elements:')nonzero_indices = np.nonzero(a)print(nonzero_indices)
# 使用这些索引访问非零元素print('\nNon-zero elements:')print(a[nonzero_indices])输出:
Original array:[[30 40 0] [ 0 20 10] [50 0 60]]
Indices of non-zero elements:(array([0, 0, 1, 1, 2, 2]), array([0, 1, 1, 2, 0, 2]))
Non-zero elements:[30 40 20 10 50 60]numpy.where()
Section titled “numpy.where()”返回给定条件为真的位置的索引。输出格式与 nonzero 类似。也可以像 三元运算符 (ternary operator) 一样使用:np.where(condition, x, y) 在条件为真时返回 x 中的元素,在条件为假时返回 y 中的元素。
示例: 使用 where
Section titled “示例: 使用 where”import numpy as np
x = np.arange(9.).reshape(3, 3)
print('Original array:')print(x)
condition = x > 3print('\nCondition (x > 3):')print(condition)
print('\nIndices where condition is true:')indices = np.where(condition)print(indices)
print('\nElements where condition is true:')print(x[indices])
# 像三元运算符一样使用 whereresult = np.where(condition, x, -1) # 将小于等于 3 的元素替换为 -1print('\nArray with elements <= 3 replaced by -1:')print(result)输出:
Original array:[[0. 1. 2.] [3. 4. 5.] [6. 7. 8.]]
Condition (x > 3):[[False False False] [False True True] [ True True True]]
Indices where condition is true:(array([1, 1, 2, 2, 2]), array([1, 2, 0, 1, 2]))
Elements where condition is true:[4. 5. 6. 7. 8.]
Array with elements <= 3 replaced by -1:[[-1. -1. -1.] [-1. 4. 5.] [ 6. 7. 8.]]numpy.extract()
Section titled “numpy.extract()”返回满足给定条件的数组元素。它在应用条件之前会将数组 展平 (flatten)。
示例: 使用 extract
Section titled “示例: 使用 extract”import numpy as np
x = np.arange(9.).reshape(3, 3)
print('Original array:')print(x)
# 定义一个条件 (例如,元素是偶数整数)condition = np.mod(x, 2) == 0
print('\nCondition (x % 2 == 0):')print(condition)
# 使用条件提取元素print('\nExtract elements using condition:')print(np.extract(condition, x))输出:
Original array:[[0. 1. 2.] [3. 4. 5.] [6. 7. 8.]]
Condition (x % 2 == 0):[[ True False True] [False True False] [ True False True]]
Extract elements using condition:[0. 2. 4. 6. 8.]