NumPy 排序、条件筛选函数(千字长文)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
一、前言
在数据分析和科学计算领域,NumPy 是 Python 生态系统中不可或缺的工具库。它为处理多维数组提供了高效且灵活的接口,而排序和条件筛选则是数据预处理中的核心操作。无论是对数据进行排序以分析趋势,还是通过条件筛选提取关键信息,NumPy 的相关函数都能帮助开发者快速实现目标。本文将从基础到进阶,结合实际案例,深入讲解 NumPy 排序 和 条件筛选函数 的使用方法,并通过形象的比喻帮助读者理解其底层逻辑。
二、NumPy 排序:让数据“各就各位”
1. 基本排序:从简单到复杂
排序是数据处理中常见的需求。NumPy 提供了 sort
函数和 argsort
函数,分别用于直接排序数据或获取排序后的索引。
numpy.sort()
:直接排序数组
sort
函数会返回排序后的数组副本,原始数组不受影响。例如:
import numpy as np
arr = np.array([3, 1, 4, 1, 5, 9, 2, 6])
sorted_arr = np.sort(arr)
print("原始数组:", arr) # 输出:[3 1 4 1 5 9 2 6]
print("排序后数组:", sorted_arr) # 输出:[1 1 2 3 4 5 6 9]
numpy.argsort()
:获取排序后的索引
argsort
返回的是排序后元素的原始索引,而非直接排序后的数组。这在需要保留原始位置信息时非常有用。例如:
indices = np.argsort(arr)
print("排序后的索引:", indices) # 输出:[1 3 6 0 2 4 7 5]
sorted_via_indices = arr[indices]
print(sorted_via_indices) # 输出:[1 1 2 3 4 5 6 9]
比喻:假设你有一排书架,sort
就像直接按书名重新排列书籍,而 argsort
则是记录每本书的新位置,方便你后续按此顺序查找。
2. 多维数组排序:灵活控制排序方向
对于二维数组(如表格数据),可以通过 axis
参数指定排序方向:
axis=0
:按列排序axis=1
:按行排序
matrix = np.array([[7, 2, 5],
[3, 8, 1],
[4, 6, 9]])
sorted_cols = np.sort(matrix, axis=0)
print("按列排序:\n", sorted_cols)
sorted_rows = np.sort(matrix, axis=1)
print("按行排序:\n", sorted_rows)
技巧:若想对二维数组的某一列进行排序后提取其他列数据,可结合 argsort
:
col_indices = np.argsort(matrix[:, 0])
sorted_second_col = matrix[col_indices, 1]
print(sorted_second_col) # 输出:[2 6 8]
3. 稳定排序与不稳定性
NumPy 的排序算法默认是不稳定的,这意味着相同值的元素可能在排序后位置发生变化。例如:
arr = np.array([2, 1, 2, 0])
sorted_arr = np.sort(arr)
print(sorted_arr) # 输出:[0 1 2 2]
若需要稳定性,可使用 sort
的 kind
参数指定算法,如 kind='mergesort'
:
stable_sorted = np.sort(arr, kind='mergesort')
print(stable_sorted) # 输出:[0 1 2 2](保持原顺序)
三、条件筛选:精准提取数据
1. 基础布尔索引:用条件“过滤”数据
布尔索引允许通过条件表达式筛选数组元素。例如:
data = np.array([10, 20, 30, 40, 50])
condition = data > 25
filtered = data[condition]
print(filtered) # 输出:[30 40 50]
扩展:条件表达式可以是任意逻辑组合,如 &
(且)、|
(或)、~
(非):
filtered = data[(data >= 20) & (data < 40)]
print(filtered) # 输出:[20 30]
2. 多条件筛选的“逻辑陷阱”
需要注意的是,布尔运算符前后必须用括号包裹,避免优先级问题:
wrong = data >= 20 & data < 40 # 实际等价于 (data >= 20) & (data < 40),但语法上需用括号
correct = (data >= 20) & (data < 40)
3. numpy.where()
:条件筛选的“进阶版”
where
函数可同时处理多个条件,并返回满足条件的元素索引或值。例如:
indices = np.where(data > 35)
print(indices) # 输出:(array([3, 4]),) → 索引3和4的元素满足条件
values = np.where(data > 35, data, -1) # 当条件成立时取 data,否则取 -1
print(values) # 输出:[ -1 -1 -1 40 50]
比喻:where
像是“条件判断器”,能根据你的规则分类数据,甚至替换成新值。
4. 多维数组的条件筛选
对二维数组筛选时,需注意索引的维度匹配。例如:
matrix = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
row_1 = matrix[1, :]
filtered_cols = matrix[:, (row_1 > 4)]
print(filtered_cols)
5. 结合排序与筛选:复杂场景的解决方案
排序和筛选常结合使用。例如,先筛选出符合条件的元素,再进行排序:
filtered = data[(data >= 10) & (data <= 30)]
sorted_filtered = np.sort(filtered)[::-1] # 反转数组实现降序
print(sorted_filtered) # 输出:[30 20 10]
四、实战案例:综合应用排序与条件筛选
案例 1:分析销售数据
假设有一个销售数据数组,包含不同产品的销售额和销量:
sales = np.array([[100, 50], # 产品A:销售额100,销量50
[200, 30], # 产品B:销售额200,销量30
[150, 40]]) # 产品C:销售额150,销量40
high_sales_low_volume = sales[(sales[:,0] > 150) & (sales[:,1] < 40)]
print(high_sales_low_volume) # 输出:[[200 30]]
案例 2:按销量排序并提取高销量产品
sorted_sales = sales[np.argsort(sales[:, 1])[::-1]] # 反转索引实现降序
print("排序后的销售数据:\n", sorted_sales)
top_two = sorted_sales[:2]
print("销量前两名:\n", top_two)
五、性能优化与注意事项
1. 避免不必要的复制
sort
函数默认返回排序后的副本,若希望直接修改原数组,可使用 arr.sort()
方法:
arr = np.array([3, 1, 2])
arr.sort() # 原数组被修改为 [1, 2, 3]
2. 大数据集的高效处理
对于大规模数据,布尔索引可能占用较多内存。此时可改用 np.nonzero
获取索引后进行操作:
indices = np.nonzero(data > 25)[0]
3. 多条件筛选的逻辑顺序
复杂条件应合理拆分,避免因优先级问题导致结果错误。例如:
condition = data > 10 and data < 20 # 需改用布尔运算符 &
condition = (data > 10) & (data < 20)
六、结论
通过本文的讲解,读者应能掌握 NumPy 排序 和 条件筛选函数 的核心用法,并能结合实际场景灵活应用。无论是对数据进行高效排序以分析趋势,还是通过条件筛选提取关键信息,NumPy 的工具链都能提供简洁且高效的解决方案。
在后续实践中,建议读者尝试以下操作:
- 对多维数组进行跨维度排序和筛选;
- 结合
mask
矩阵实现更复杂的逻辑判断; - 通过性能测试对比不同方法的效率差异。
掌握这些技能后,你将能够更自信地处理真实世界的复杂数据挑战!