讲师中心 微信公众号
AI工具推荐 视频效率加速

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

大磊酱_9863

大磊酱_9863

发布时间:2025-11-30 12:22:18

|

637人浏览过

|

来源于php中文网

原创

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方法的一个特例,专门用于查找指定索引区间内的最大值。

macOS UI 自动化技能包 —— 用 Python 控制你的 Mac
macOS UI 自动化技能包 —— 用 Python 控制你的 Mac

让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限

下载

np.ufunc.reduceat(array, indices) 的核心思想是,它会在indices数组中指定的每个起始索引处“重置”累积操作。对于np.maximum.reduceat,这意味着它会从每个指定索引开始,计算直到下一个指定索引(或数组末尾)的最大值。

关键步骤:为了获得与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]

代码解释:

  1. arr = np.arange(12): 创建一个包含0到11的NumPy数组。
  2. ind = np.array([3, 5, 9]): 定义分割点。这些索引是每个子数组的起始索引(除了第一个子数组的起始索引0)。
  3. full_indices = np.concatenate(([0], ind)): 这是最关键的一步。np.maximum.reduceat需要所有子数组的起始索引。由于ind只包含了后续子数组的起始索引,我们需要手动添加第一个子数组的起始索引 0。
    • [0]:代表第一个子数组的起始索引。
    • ind:代表后续子数组的起始索引。
    • np.concatenate将它们合并成 [0, 3, 5, 9]。
  4. 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编程效率和解决复杂数据处理问题的关键技能之一。

热门AI工具

更多
蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

相关专题

更多
go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

1872

2025.09.03

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

60

2026.10.22

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

40

2026.10.22

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

40

2026.10.22

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

20

2026.10.22

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

20

2026.10.22

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

20

2026.10.22

Golangci-lint安装与入门教程
Golangci-lint安装与入门教程

本专题讲解Golangci-lint的安装、初始化、基础命令和首次代码检查,覆盖本地环境、Docker及多平台用法,帮助Go开发者快速上手。

20

2026.10.22

PHP2Shell高危漏洞修复教程
PHP2Shell高危漏洞修复教程

PHP2Shell漏洞是什么,哪些PHP版本和运行环境会受到影响,服务器应该如何检测与修复?本专题提供版本自查脚本、Linux与Docker升级命令、PHP-FPM和Apache排查步骤,以及修复验证、临时缓解和应急响应方案。

160

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn