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

NumPy reduceat:高效向量化查找分段数组最大值

风涛吖_8407

风涛吖_8407

发布时间:2025-12-13 16:14:51

|

164人浏览过

|

来源于php中文网

原创

numpy reduceat:高效向量化查找分段数组最大值

本教程深入探讨了如何使用 NumPy 的 `np.maximum.reduceat` 函数,以高效、向量化的方式查找一维数组中逻辑分段子数组的最大值,而无需先进行显式拆分。文章将详细介绍 `reduceat` 的工作原理,并强调在索引数组中包含起始索引 `0` 的重要性,通过具体示例展示其简洁且高性能的实现。

在数据处理和科学计算中,我们经常需要对数组的特定分段(或逻辑子数组)执行聚合操作,例如查找最大值、最小值或求和。当这些分段由一系列索引定义时,一个常见的直观做法是先使用 numpy.split 将原数组拆分成子数组列表,然后遍历这些子数组进行操作。然而,对于大型数据集,这种方法涉及显式的数组拆分和 Python 循环,效率往往不高,与 NumPy 的向量化设计理念相悖。

本教程将介绍一种更高效、更符合 NumPy 风格的解决方案:利用 np.ufunc.reduceat 函数。这个强大的工具能够直接在原始数组上执行分段聚合,避免了中间的数组创建和循环开销。

理解 np.ufunc.reduceat

np.ufunc.reduceat(array, indices) 是 NumPy 通用函数(ufunc)的一个特殊方法。它允许你在 array 上,从 indices 中指定的每个位置开始,应用 ufunc(例如 maximum, sum, add 等)进行累积操作。具体来说,它会在 indices 中的每个索引处启动一个新的“规约”(reduction)过程,并将该规约的结果存储在输出数组的对应位置。

对于查找分段最大值的问题,我们将使用 np.maximum.reduceat。它的核心思想是:

  • 在 indices 数组中指定的每个位置开始计算一个最大值。
  • 这个最大值计算会持续到下一个 indices 中指定的索引位置之前,或者直到数组的末尾。
  • 最终结果数组的长度将与 indices 数组的长度相同。

关键:准备正确的起始索引

为了让 np.maximum.reduceat 正确地处理所有分段,特别是第一个分段,我们必须确保 indices 数组包含了所有分段的起始索引。这意味着,如果你的分段是从数组的第一个元素开始的,那么 indices 数组中必须包含 0。

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

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

下载

假设我们有一个一维数组 arr 和一个表示分割点的索引数组 ind。ind 中的值表示在这些位置之后进行分割。例如,ind = [3, 5, 9] 意味着在索引 3 之前、索引 5 之前、索引 9 之前进行分割。为了使用 reduceat,我们需要提供每个分段的 起始 索引。

  • 第一个分段从索引 0 开始。
  • 第二个分段从 ind[0] (即 3) 开始。
  • 第三个分段从 ind[1] (即 5) 开始。
  • 第四个分段从 ind[2] (即 9) 开始。

因此,我们需要将原始的 ind 数组与 [0] 进行拼接,形成一个新的索引数组,作为 reduceat 的第二个参数。

示例:向量化查找分段最大值

让我们通过一个具体的例子来演示如何使用 np.maximum.reduceat。

import numpy as np

# 原始一维数组
arr = np.arange(12)
print("原始数组 arr:", arr)
# 输出: 原始数组 arr: [ 0  1  2  3  4  5  6  7  8  9 10 11]

# 分割点索引 (表示在这些索引处之后进行分割)
# 逻辑上将 arr 分割为:
# [0, 1, 2] -> max = 2
# [3, 4]    -> max = 4
# [5, 6, 7, 8] -> max = 8
# [9, 10, 11] -> max = 11
ind = np.array([3, 5, 9])
print("分割点索引 ind:", ind)
# 输出: 分割点索引 ind: [3 5 9]

# 准备用于 reduceat 的完整起始索引数组
# 必须包含 0 作为第一个分段的起始点
# 拼接后得到 [0, 3, 5, 9]
start_indices = np.concatenate(([0], ind))
print("用于 reduceat 的起始索引:", start_indices)
# 输出: 用于 reduceat 的起始索引: [0 3 5 9]

# 使用 np.maximum.reduceat 查找每个分段的最大值
max_values = np.maximum.reduceat(arr, start_indices)

print("每个分段的最大值:", max_values)
# 预期输出: 每个分段的最大值: [ 2  4  8 11]

代码解释:

  1. arr = np.arange(12) 创建了一个从 0 到 11 的一维数组。
  2. ind = np.array([3, 5, 9]) 定义了逻辑上的分割点。
  3. start_indices = np.concatenate(([0], ind)) 是最关键的一步。它将 0(代表 arr 的起始索引)与 ind 数组连接起来,生成 [0, 3, 5, 9]。这个新的数组 start_indices 准确地告诉 reduceat 每个分段的起始位置。
    • 第一个分段从索引 0 开始,到索引 3 之前结束(即 arr[0:3])。
    • 第二个分段从索引 3 开始,到索引 5 之前结束(即 arr[3:5])。
    • 第三个分段从索引 5 开始,到索引 9 之前结束(即 arr[5:9])。
    • 第四个分段从索引 9 开始,到数组末尾结束(即 arr[9:])。
  4. np.maximum.reduceat(arr, start_indices) 执行了向量化的分段最大值查找。它返回一个数组,其中每个元素对应于 start_indices 中相应索引所开始的分段的最大值。

优点与注意事项

  • 性能提升: 相较于 np.split 结合 Python 列表推导式,reduceat 完全在 C 语言层面执行,避免了 Python 循环的开销和中间子数组的内存分配,对于大型数组具有显著的性能优势。
  • 代码简洁性: 解决方案简洁明了,一行代码即可实现复杂的分段聚合逻辑。
  • 通用性: reduceat 不仅限于 maximum。你可以将其与任何 NumPy 的通用函数(ufunc)结合使用,例如 np.add.reduceat 求和,np.minimum.reduceat 求最小值,np.multiply.reduceat 求乘积等。
  • 索引数组要求: indices 数组必须是已排序的,并且其中的值必须在 [0, len(array)-1] 范围内。
  • 多维数组: reduceat 也可以用于多维数组,但需要指定 axis 参数,本教程主要关注一维数组的场景。

总结

np.ufunc.reduceat 是 NumPy 中一个强大且高效的工具,用于在不显式分割数组的情况下执行分段聚合操作。通过正确构造包含所有分段起始索引的 indices 数组(特别是要包含 0),我们可以轻松实现如查找分段最大值等任务,从而编写出更高效、更符合 NumPy 风格的代码。掌握这一技巧将极大地提升你在处理大规模数值数据时的效率和代码质量。

热门AI工具

更多
Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

WorkBuddy

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

超级简历WonderCV

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

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

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

DeepSeek

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

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

豆包大模型

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

VibeKnow
VibeKnow Hot

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

相关专题

更多
Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

40

2026.10.28

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

20

2026.10.28

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

0

2026.10.28

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

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

120

2026.10.22

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

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

80

2026.10.22

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

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

60

2026.10.22

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

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

40

2026.10.22

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

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

60

2026.10.22

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

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

40

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