新闻中心
NumPy矢量化:高效查找子数组的最大值

本教程详细阐述如何利用numpy库的`np.maximum.reduceat`函数,以纯矢量化方式高效地计算一维数组按指定索引“分割”后各子数组的最大值。通过巧妙地构造索引数组,该方法避免了显式数组分割和python循环,显著提升了处理效率和代码的简洁性,是处理此类问题的numpy风格最佳实践。
在数据处理中,我们经常需要对一个一维NumPy数组进行逻辑上的“分割”,并对每个分割后的子数组执行聚合操作,例如查找最大值。传统的做法是先使用numpy.split将原始数组分割成子数组列表,然后遍历这个列表,对每个子数组调用其.max()方法。
考虑以下示例,我们有一个数组arr和一组分割点ind:
import numpy as np
arr = np.arange(12) # arr 为 array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
ind = np.array([3, 5, 9]) # 在索引3, 5, 9处进行分割
# 传统方法:先分割,再遍历查找最大值
sub_arrays = np.split(arr, ind)
# sub_arrays 结果: [array([0, 1, 2]), array([3, 4]), array([5, 6, 7, 8]), array([ 9, 10, 11])]
max_values_traditional = [sub_array.max() for sub_array in sub_arrays]
# max_values_traditional 结果: [2, 4, 8, 11]
print(f"传统方法得到的最大值: {max_values_traditional}")尽管上述方法直观易懂,但它涉及了显式的数组分割操作和Python级别的循环。在大规模数据处理时,这种方法可能导致性能瓶颈,并且不符合NumPy倡导的矢量化计算哲学。
矢量化解决方案:使用 np.maximum.reduceat
NumPy提供了一个更高效、更符合矢量化思想的解决方案:np.maximum.reduceat。这个函数是通用函数(ufunc)reduceat方法的一个特例,专门用于查找指定索引区间内的最大值。
np.ufunc.reduceat(array, indices) 的核心思想是,它会在indices数组中指定的每个起始索引处“重置”累积操作。对于np.maximum.reduceat,这意味着它会从每个指定索引开始,计算直到下一个指定索引(或数组末尾)的最大值。
易通cmseasy免费的企业建站程序2.0 UTF-8 build 201000510 中文版
易通(企业网站管理系统)是一款小巧,高效,人性化的企业建站程序.易通企业网站程序是国内首款免费提供模板的企业网站系统.§ 简约的界面及小巧的体积:后台菜单完全可以修改成自己最需要最高效的形式;大部分操作都集中在下拉列表框中,以节省更多版面来显示更有价值的数据;数据的显示以J*ascript数组类型来输出,减少数据的传输量,加快传输速度。 § 灵活的模板标签及模
0
查看详情
关键步骤:为了获得与np.split后.max()完全一致的结果,传递给reduceat的索引数组必须包含原始数组的起始索引 0。
import numpy as np
arr = np.arange(12) # 原始数组
ind = np.array([3, 5, 9]) # 分割点索引
# 构造包含起始索引0的完整索引数组
# np.concatenate(([0], ind)) 会得到 [0, 3, 5, 9]
# 这表示我们希望计算从索引0开始到索引2的最大值,从索引3开始到索引4的最大值,
# 从索引5开始到索引8的最大值,以及从索引9开始到数组末尾的最大值。
full_indices = np.concatenate(([0], ind))
# 使用 np.maximum.reduceat 进行矢量化计算
max_values_vectorized = np.maximum.reduceat(arr, full_indices)
print(f"矢量化方法得到的最大值: {max_values_vectorized}")
# 预期输出: [ 2 4 8 11]代码解释:
- arr = np.arange(12): 创建一个包含0到11的NumPy数组。
- ind = np.array([3, 5, 9]): 定义分割点。这些索引是每个子数组的起始索引(除了第一个子数组的起始索引0)。
- full_indices = np.concatenate(([0], ind)): 这是最关键的一步。np.maximum.reduceat需要所有子数组的起始索引。由于ind只包含了后续子数组的起始索引,我们需要手动添加第一个子数组的起始索引 0。
- [0]:代表第一个子数组的起始索引。
- ind:代表后续子数组的起始索引。
- np.concatenate将它们合并成 [0, 3, 5, 9]。
- max_values_vectorized = np.maximum.reduceat(arr, full_indices):
- reduceat会从 full_indices 中的每个索引开始,应用 maximum 操作。
- 从索引 0 开始,计算 arr[0:3] (即 [0, 1, 2]) 的最大值,结果是 2。
- 从索引 3 开始,计算 arr[3:5] (即 [3, 4]) 的最大值,结果是 4。
- 从索引 5 开始,计算 arr[5:9] (即 [5, 6, 7, 8]) 的最大值,结果是 8。
- 从索引 9 开始,计算 arr[9:] (即 [9, 10, 11]) 的最大值,结果是 11。
- 最终结果 [2, 4, 8, 11] 正是所有子数组的最大值。
优势与注意事项
- 性能提升: np.maximum.reduceat 是在C语言层面实现的,避免了Python循环的开销,对于大型数组而言,其性能远超np.split结合列表推导式的方法。
- 内存效率: 这种方法不需要创建中间的子数组列表,从而减少了内存开销。
- 通用性: reduceat不仅限于maximum,还可以与NumPy的许多其他通用函数(如np.add.reduceat、np.sum.reduceat、np.amin.reduceat等)结合使用,实现各种分段聚合操作。
- 索引数组要求: 传递给reduceat的indices数组必须是升序的。如果索引不按升序排列,结果将是未定义的。
- 边界条件: 确保full_indices中的最后一个索引小于arr的长度。如果最后一个索引等于或大于arr的长度,reduceat会正确处理,但可能导致空切片或不符合预期的结果。
总结
当需要对NumPy数组进行逻辑分割并对每个分段执行聚合操作(如查找最大值、求和等)时,np.ufunc.reduceat 提供了一种强大且高效的矢量化解决方案。通过正确构造包含起始索引0的索引数组,我们可以避免显式分割和Python循环,从而编写出更简洁、性能更优的NumPy代码。掌握reduceat的使用,是提升NumPy编程效率和解决复杂数据处理问题的关键技能之一。
以上就是NumPy矢量化:高效查找子数组的最大值的详细内容,更多请关注其它相关文章!
# 遍历
# 临汾昌吉网站建设
# 专卖店怎么推广营销方案
# 莱阳冷库推广招聘网站
# 福州seo高级方法
# 柳江区实用的网络营销推广
# 石龙网站建设价位
# 网站推广文章范例
# 外贸平台网站怎么做推广
# 苏州网站优化建设
# 龙口seo推广平台
# 转换为
# 并对
# python
# 结果是
# 升序
# 企业网站
# 数据处理
# 企业建站
# 易通
# 矢量化
# red
# 排列
# 性能瓶颈
# c语言
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
mysql密码锁定怎么解锁_mysql密码锁定解锁后修改密码步骤
荒野行动PC版怎么注册_荒野行动PC版账号注册详细流程图文教程
win11如何加载ICC颜色配置文件 Win11校色文件安装与显示器色彩管理【指南】
Golang如何优化内存分配与垃圾回收_Golang内存管理与GC优化实践
字由网在线版登录地址 字由网网页版安全入口
Spring Boot嵌入式服务器与J*a EE:功能支持深度解析
漫蛙Manwa2官网入口地址分享 漫蛙漫画PC版永久访问通道
Adobe PDF表单中利用J*aScript解析与格式化日期组件的教程
Gmail邮箱申请注册直达_Gmail邮箱免费注册PC版官网入口2025
不同用户不同价格! 索尼开启账户个性化定价测试
理解Python模块与全局变量的作用域管理
c++中的const_cast和reinterpret_cast怎么用_c++四种类型转换
漫蛙2正版漫画站 漫蛙2网页版快速访问入口
KFC套餐升级怎么获取优惠代码_KFC套餐升级活动与优惠代码获取方法
夸克浏览器图书入口 夸克手机浏览器阅读入口
qq浏览器打开空白页怎么办 qq浏览器启动后显示白屏的解决教程
知音漫客正版漫画平台_知音漫客官网账号登录
纯CSS与HTML网格布局的HTML精简策略:SVG与JS方案解析
正确连接J*aScript到HTML实现可点击图片与自定义事件处理
12306选座怎么选到特殊座位_12306特殊座位选择注意事项
如何使用CaptainHook和Composer管理Git钩子_在提交前自动运行代码检查的Composer配置
Golang如何通过reflect获取匿名字段方法_Golang reflect匿名字段方法访问技巧
期待已久:小米17 Ultra、小米首款NAS本月登场
漫蛙官网正版漫画入口 漫蛙2官方网页登录地址
C++如何使用AddressSanitizer(ASan)_C++调试工具中检测内存访问错误的利器
PrimeNG Sidebar背景色自定义指南:CSS覆盖与主题化实践
CSS自定义字体样式被系统字体替换怎么办_font-face方式指定font-display控制渲染策略
LINQ to XML为何解析失败? 深入理解C# XDocument的异常处理
Mac怎么锁定备忘录_Mac备忘录加密设置教程
PHP高效扁平化嵌套数组:使用array_merge与数组解包操作符
EMS快递官网app_中国邮政速递物流手机客户端
豆包手机助手发布技术预览版:直接嵌入手机系统!努比亚样机发售
优酷会员付费后没到账怎么办_优酷会员充值异常及解决方法
html怎么在cmd下运行php文件_cmd运行html中php文件方法【教程】
Win11如何使用Windows Sandbox Win11沙盒功能开启与使用教程【详解】
Python中高效且防溢出的双曲正弦计算:基于对数空间的优化策略
使用CSS更改登录屏幕输入框中PNG图标颜色的策略与局限性
荣耀Play7TPro怎样在信息App置顶客服对话_iPhone荣耀Play7TPro信息App置顶客服对话【优先查看】
Flexbox布局实践:实现粘性导航栏与底部固定页脚
单12V-2×6实现为RTX 5090供电750W!甚至都没敢跑分
Win11怎么开启卓越性能模式 Win11电源选项启用高性能释放硬件潜力【方法】
深入理解字体排版:Adobe光学字偶距与CSS字偶距的差异与实现
12306怎么选座位选到安静区_12306选座安静区域选择策略
斑马英语APP如何开启夜间护眼阅读_斑马英语APP夜间模式与低蓝光设置教程
C#使用XPath查询节点时出错? 常见语法错误与调试技巧
c++如何实现一个简单的软件渲染器_c++从零开始的3D图形学
React/Next.js中实现列表项的动态移动与状态管理:兼论唯一键的重要性
c++如何使用Meson构建系统_c++比CMake更快的构建工具
钉钉视频会议画面卡顿如何解决 钉钉会议画面优化方法
Node.js CSV 数据处理:基于字段空值条件过滤整条记录的策略


2025-11-30
浏览次数:次
返回列表