Python NumPy自定义排序算法实现
排序是数据处理和分析中的基本操作。虽然 NumPy 提供了高效的内置排序函数(如 numpy.sort 和 numpy.argsort),但有时需要实现自定义的排序逻辑,以满足特定需求,例如对数组中的特定列、组合条件或自定义顺序进行排序。
NumPy 内置排序方法在开始自定义排序算法之前,先了解 NumPy 提供的内置排序功能:
numpy.sort:对数组进行排序,默认沿最后一个轴进行排序。numpy.argsort:返回排序后的索引。numpy.lexsort:用于基于多个键的排序。使用 NumPy 内置排序方法代码语言:javascript代码运行次数:0运行复制import numpy as np
# 一维数组排序
arr = np.array([3, 1, 4, 1, 5, 9])
sorted_arr = np.sort(arr)
print("排序后的数组:", sorted_arr)
# 二维数组按列排序
arr2d = np.array([[3, 7], [1, 9], [4, 6]])
sorted_arr2d = np.sort(arr2d, axis=0)
print("二维数组按列排序:\n", sorted_arr2d)
输出:
代码语言:javascript代码运行次数:0运行复制排序后的数组: [1 1 3 4 5 9]
二维数组按列排序:
[[1 6]
[3 7]
[4 9]]
这些方法对常见的排序任务非常高效,但当需要复杂逻辑时,可以基于 NumPy 实现自定义排序算法。
自定义排序算法实现自定义排序算法可以通过以下几种方式实现:
方法一:基于索引的排序可以通过 numpy.argsort 获取排序后的索引,然后根据这些索引重新排列数组。
代码语言:javascript代码运行次数:0运行复制# 自定义权重
weights = np.array([2, 3, 1, 5])
# 数组排序
arr = np.array([10, 20, 30, 40])
# 获取按权重排序的索引
sorted_indices = np.argsort(weights)
# 根据索引重排数组
sorted_arr = arr[sorted_indices]
print("按权重排序后的数组:", sorted_arr)
输出:
代码语言:javascript代码运行次数:0运行复制按权重排序后的数组: [30 10 20 40]
方法二:基于条件的排序自定义排序逻辑可以通过 NumPy 的布尔索引和矢量化函数实现。
将数组中的偶数放在前面,奇数放在后面,同时保持每部分的升序。
代码语言:javascript代码运行次数:0运行复制# 自定义数组
arr = np.array([9, 4, 1, 6, 8, 3, 7])
# 偶数部分
evens = np.sort(arr[arr % 2 == 0])
# 奇数部分
odds = np.sort(arr[arr % 2 != 0])
# 合并结果
custom_sorted = np.concatenate((evens, odds))
print("按奇偶性排序后的数组:", custom_sorted)
输出:
代码语言:javascript代码运行次数:0运行复制按奇偶性排序后的数组: [4 6 8 1 3 7 9]
方法三:多键排序多键排序类似于数据库中的多列排序,可以通过 numpy.lexsort 实现。
代码语言:javascript代码运行次数:0运行复制# 创建二维数组
arr = np.array([
[10, 20],
[5, 30],
[10, 10],
[5, 20]
])
# 按第1列和第0列排序
sorted_indices = np.lexsort((arr[:, 0], arr[:, 1]))
sorted_arr = arr[sorted_indices]
print("按多个键排序后的数组:\n", sorted_arr)
输出:
代码语言:javascript代码运行次数:0运行复制按多个键排序后的数组:
[[10 10]
[5 20]
[10 20]
[5 30]]
方法四:自定义排序函数通过 NumPy 的 vectorize 和 argsort,可以定义更加复杂的排序逻辑。
代码语言:javascript代码运行次数:0运行复制# 定义数组
arr = np.array([-10, 5, -3, 8, -2])
# 获取按绝对值排序的索引
sorted_indices = np.argsort(np.abs(arr))
# 根据索引重排数组
sorted_arr = arr[sorted_indices]
print("按绝对值排序后的数组:", sorted_arr)
输出:
代码语言:javascript代码运行次数:0运行复制按绝对值排序后的数组: [-2 -3 5 8 -10]
自定义排序的实际应用应用一:字符串数组排序对于字符串数组,可以按长度或特定字符排序。
代码语言:javascript代码运行次数:0运行复制# 定义字符串数组
strings = np.array(["apple", "pear", "banana", "cherry"])
# 按字符串长度排序
sorted_indices = np.argsort([len(s) for s in strings])
sorted_strings = strings[sorted_indices]
print("按长度排序后的字符串数组:", sorted_strings)
输出:
代码语言:javascript代码运行次数:0运行复制按长度排序后的字符串数组: ['pear' 'apple' 'cherry' 'banana']
应用二:复杂数据结构排序对于包含多个字段的结构化数组,可以基于指定字段进行排序。
代码语言:javascript代码运行次数:0运行复制# 定义结构化数组
data = np.array([
(1, 'Alice', 25),
(2, 'Bob', 30),
(3, 'Charlie', 20)
], dtype=[('id', 'i4'), ('name', 'U10'), ('age', 'i4')])
# 按 age 字段排序
sorted_data = np.sort(data, order='age')
print("按年龄排序后的数据:", sorted_data)
输出:
代码语言:javascript代码运行次数:0运行复制按年龄排序后的数据:
[(3, 'Charlie', 20) (1, 'Alice', 25) (2, 'Bob', 30)]
应用三:矩阵按行或列排序代码语言:javascript代码运行次数:0运行复制# 创建矩阵
matrix = np.array([
[5, 4, 3],
[2, 8, 7],
[1, 6, 9]
])
# 按每行的最大值排序
sorted_indices = np.argsort(matrix.max(axis=1))
sorted_matrix = matrix[sorted_indices]
print("按每行最大值排序后的矩阵:\n", sorted_matrix)
输出:
代码语言:javascript代码运行次数:0运行复制按每行最大值排序后的矩阵:
[[5 4 3]
[2 8 7]
[1 6 9]]
实现自定义排序算法实现冒泡排序代码语言:javascript代码运行次数:0运行复制# 自定义冒泡排序
def bubble_sort(arr):
n = len(arr)
for i in range(n):
for j in range(0, n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
# 测试自定义排序
arr = np.array([64, 34, 25, 12, 22, 11, 90])
sorted_arr = bubble_sort(arr.copy())
print("冒泡排序结果:", sorted_arr)
输出:
代码语言:javascript代码运行次数:0运行复制冒泡排序结果: [11 12 22 25 34 64 90]
虽然 NumPy 已有高效的排序方法,但通过这种方式,可以实现特定的排序逻辑。
总结本文详细介绍了 Python NumPy 中实现自定义排序算法的方法,包括基于索引、条件、多键排序以及自定义函数的排序。通过这些方法,可以灵活地满足不同场景下的排序需求。
此外,本文还结合实际案例展示了字符串排序、复杂数据结构排序以及矩阵排序的高级用法。掌握这些技巧,不仅能提高代码的灵活性和效率,还能解决更复杂的数据处理问题。在实际工作中,合理选择合适的排序方法,可以显著优化数据处理流程。