当前位置: 首页 > news >正文

NumPy 2.x 完全指南【三十】整数数组索引

文章目录

  • 1. 高级索引
  • 2. 整数数组索引(花式索引)
    • 2.1 一维数组
    • 2.2 二维数组
      • 2.2.1 部分索引
      • 2.1.2 全索引
    • 2.3 三维数组
      • 2.3.1 部分索引
      • 2.3.1 全索引

1. 高级索引

NumPy 中,高级索引允许通过非连续的、复杂的规则选择数组中的元素,支持以下两种类型:

  • 整数数组索引
  • 布尔数组索引

注意事项:

  • 高级索引总是返回数据的副本(copy)而非视图(切片返回视图)。
  • 当索引对象满足以下任一条件时,才会触发高级索引:
    • 非元组的序列对象:如列表(list)或嵌套列表。
    • 整数或布尔类型的 ndarray:数组元素为整数或布尔值。
    • 包含至少一个序列或 ndarray 的元组:元组中存在列表、数组等非标量索引对象。

示例,x[(1, 2, 3)] 的索引对象是一个元组,不满足上面任一条件,是一个普通索引等价于 x[1, 2, 3],表示取第 234 位置的元素:

arr = np.arange(64).reshape(4, 4, 4)
print(arr)# 基本索引示例
result = arr[(1, 2, 3)]
print(result)  # 输出:27# 等效于
result_basic = arr[1, 2, 3]
print(result_basic)  # 同样输出:27

x[(1, 2, 3),] 中有一个逗号,元组中包含元组,符合了包含至少一个序列的元组的条件,属于高级索引对象。

2. 整数数组索引(花式索引)

定义:通过整数数组指定要访问元素的索引位置。

假设数组的形状为 (d1, d2, …, dn),整数数组索引的基本表达式为:

# index_1, index_2,...:索引对象,作用于对应的维度
arr[index_1, index_2, ..., index_k]

核心规则:

  • 维度填充:索引对象数量 < 数组维度 缺失维度自动补 :
  • 索引数组的配对与广播
    • 所有索引数组会先广播到相同形状(如果可以)。
    • 广播后的索引数组中的每个元素(按位置)组合成一个坐标元组,用于索引原始数组。
  • 输出形状
    • 全索引(索引数组数量 = 数组维度):输出形状 = 广播后的索引数组形状。
    • 部分索引(索引数组数量 < 数组维度):输出形状 = 广播后的索引数组形状 + 剩余维度的完整大小。

2.1 一维数组

一维数组只有一个轴,维度数也是一,索引表达式为 arr[index],所以不涉及维度填充,也不涉及部分索引。结果数组的形状完全和索引数组对象的形状一致,因为索引值对应的是标量元素。

示例 1 ,索引对象为一维数组时,结果数组的形状和索引对象一致,然后将对应索引位置的元素映射到结果数组中:

# 创建基础一维数组
arr = np.arange(10, 0, -1)  # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
"""
索引:0  1  2  3  4  5  6  7  8  9
值: 10 9  8  7  6  5  4  3  2  1
"""# 索引对象
index_arr = [2, 4, 5]
# 获取 arr 在 [2, 4, 5] 索引处的元素
print(arr[index_arr])  # [8 6 5]# 获取 arr 在 [-2, 1, 6] 索引处的元素(包含负索引)
print(arr[np.array([-2, 1, 6])])  # [2 9 4]

执行过程如下所示:
在这里插入图片描述

如果索引值越界,会抛出 IndexError 异常:

# 索引对象为 ndarray
index_arr = np.array([1, 4, 20])
# 获取 arr 在 [1, 4, 20] 索引处的元素
print(arr[index_arr]) # IndexError: index 20 is out of bounds for axis 0 with size 10

示例 2 ,索引对象为二维数组时,也是一样的执行流程:

# 索引对象 (2,3)
index_arr = np.array([[1, 2, 3],[4, 5, 6]])
print(arr[index_arr])
# [[9 8 7]
#  [6 5 4]]

执行过程如下所示:
在这里插入图片描述

示例 3 ,索引对象为三维或更高维度的数组时,也是同样的执行流程:

# 索引对象 (2, 2, 3)
index_arr = np.array([[[1, 0, 2],[2, 1, 0]],[[1, 2, 3],[2, 3, 3]]])
print(arr[index_arr])
# [[[ 9 10  8]
#   [ 8  9 10]]
#  [[ 9  8  7]
#   [ 8  7  7]]]

2.2 二维数组

二维数组有两个轴,高级索引表达式可以有以下几种形式:

  • arr[index1,index2](全索引)。
  • arr[index1] (部分索引)。

2.2.1 部分索引

arr[index1] (部分索引):仅作用于轴 0(行),默认轴 1 完全保留,等效于arr[index, :]

示例 1 ,单个一维的索引对象时,每个索引值映射到哪一行:

# 二维数组
arr = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])# 一维索引数组
# 0:第一行
# 2:第三行
index = [0, 2]
result = arr[index]
print(result)
#  [[1 2 3]
#  [7 8 9]]

示例 2 ,索引对象为二维数组使用 arr[index] 时,每个索引值也表示哪一行,然后填充到结果数组中:

# 二维数组
arr = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])# 二维索引数组
index = [[0, 1], [1, 2]]
# 结果:
# [[0 行, 1 行], [1 行 , 2 行]]
result = arr[index]
print(result)
# [[[1 2 3]
#   [4 5 6]]
#
#  [[4 5 6]
#   [7 8 9]]]

示例 3 ,索引对象为更高维度数组时,arr[index] 也是一样:

# 三维索引数组
index = [[[0, 1], [1, 2]]]
# 结果:
# [[[0 行, 1 行], [1 行 , 2 行]]]
result = arr[index]
print(result)
# [[[[1 2 3]
#    [4 5 6]]
#
#   [[4 5 6]
#    [7 8 9]]]]

2.1.2 全索引

arr[index1,index2](全索引) :同时作用于轴 0(行)和轴 1(列)。

示例 1 ,多个相同形状的一维的索引对象时,会直接进行索引配对,将索引数组中的每个元素(按位置)组合成一个坐标元组,然后根据坐标获取到对应元素进行填充:

index1 = [0, 2]  # 行索引
index2 = [1, 1]  # 列索引
# 配对:[(0,1),(2,1)]
result = arr[index1, index2]
print(result)
#  [2 8]

示例 2 ,当多不同形状的一维的索引对象时,无法进行一一配对,会尝试进行广播,如果它们的长度不一样,且其中一个的长度不为 1 ,无法满足广播条件引发错误:

index1 = [0, 2]  # 行索引
index2 = [1, 1, 1]  # 列索引
result = arr[index1, index2]
# IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,)

示例 3 ,满足广播机制时,index2 会被广播为 [0,0] ,然后再进行索引配对:

index1 = [0, 2]  # 行索引
index2 = [0]  # 列索引 广播为 `[0,0]`
# 第一组索引:(0, 0) -> 行 0 列 1 的元素是 1
# 第二组索引:(2, 0) -> 行 2 列 0 的元素是 7
result = arr[index1, index2]
print(result) # [1 7]

示例 4 ,对更高维度的索引对象,也会先进行广播,然后配对映射,再将索引对应位置的元素填充到结果数组:

# 创建行索引和列索引
row_idx = np.array([[0, 1],[1, 2]])
col_idx = np.array([[1, 1],[2, 2]])# 配对:
# [[(0 行 1 列 ), (1 行 1 列)],
#  [(1 行 2 列), (2 行 2 列)]]# 同时索引行和列
result = arr[row_idx, col_idx]
print(result)
# [[2 5]
#  [6 9]]

2.3 三维数组

三维或者更好维度的数组,其索引规则也是一样,比如三维数组索引表达式可以有以下几种形式:

  • arr[index1,index2,index3] (全索引):同时作用于所有轴。
  • arr[index1,index2] (部分索引):等效于arr[index1,index2, :]
  • arr[index1] (部分索引):等效于arr[index1,:, :]

2.3.1 部分索引

示例 1 ,arr[index1] 不涉及索引配对,每个索引只作用于 0 轴,每个索引对应的结果为子数组(二维)。这里索引对象是一维的,索引值对应的结果是二维的,所以填充返回的结果是三维的(1+2):

# 创建一个 3 x 3 x 3三维数组
arr = np.arange(27).reshape(3, 3, 3)
"""
arr_3d 结构:
第一层: [[ 0,  1,  2],[ 3,  4,  5],[ 6,  7,  8]]第二层: [[ 9, 10, 11],[12, 13, 14],[15, 16, 17]]第三层: [[18, 19, 20],[21, 22, 23],[24, 25, 26]]
"""
# [0 层, 1 层]=》 结果为三维数组
index1 = np.array([0, 1])result = arr[index1]
# 等效于 arr[index1, :, :]
print(result)
# [[[ 0  1  2]
#   [ 3  4  5]
#   [ 6  7  8]]
#
#  [[ 9 10 11]
#   [12 13 14]
#   [15 16 17]]]

示例 2 ,arr[index1,index2] 获取到行并填充到结果数组:

index1 = np.array([0, 1])
index2 = np.array([1, 2])
# 配对:
# [(0 层 1 行 ),(1 层 2 行)]result = arr[index1,index2]
print(result)
# [[ 3  4  5]
#  [15 16 17]]

示例 3 ,arr[index] 形式下的二维索引对象:

# 二维索引数组
index = [[0, 1], [1, 2]]
# 结果:
# [[0 层, 1 层], [1 层 , 2 层]]
result = arr[index]
print(result)
# [[[[ 0  1  2]
#    [ 3  4  5]
#    [ 6  7  8]]
#
#   [[ 9 10 11]
#    [12 13 14]
#    [15 16 17]]]
#
#
#  [[[ 9 10 11]
#    [12 13 14]
#    [15 16 17]]
#
#   [[18 19 20]
#    [21 22 23]
#    [24 25 26]]]]

示例 4 ,arr[index] 形式下的三维索引对象:

# 二维索引数组
index = [[[0, 1], [1, 2]],[[1, 1], [1, 2]]]
# 结果:
# [[[0 层 , 1 层], [1 层, 2 层]],
#      [[1 层, 1 层 ], [1 层, 2 层]]]
result = arr[index]
print(result)
# [[[[[ 0  1  2]
#     [ 3  4  5]
#     [ 6  7  8]]
#
#    [[ 9 10 11]
#     [12 13 14]
#     [15 16 17]]]
#
#
#   [[[ 9 10 11]
#     [12 13 14]
#     [15 16 17]]
#
#    [[18 19 20]
#     [21 22 23]
#     [24 25 26]]]]
#
#
#
#  [[[[ 9 10 11]
#     [12 13 14]
#     [15 16 17]]
#
#    [[ 9 10 11]
#     [12 13 14]
#     [15 16 17]]]
#
#
#   [[[ 9 10 11]
#     [12 13 14]
#     [15 16 17]]
#
#    [[18 19 20]
#     [21 22 23]
#     [24 25 26]]]]]

示例 5 ,arr[index1,index2] 形式下的二维索引对象:

index1 = np.array([[0, 1],[0, 1]])
index2 = np.array([[0, 2],[0, 2]])# 配对:
# [[(0 层 0 行 ),(1 层 2 行)]
# ,[(0 层 0 行 ),(1 层 2 行)]]result = arr[index1,index2]
print(result)
# [[[ 0  1  2]
#   [15 16 17]]
#
#  [[ 0  1  2]
#   [15 16 17]]]

2.3.1 全索引

示例 1 ,arr[index1,index2,index3] 形式时也会进行广播机制 + 索引配对,获取单个元素并填充到结果数组:

index1 = np.array([0, 1])
index2 = np.array([1, 2])
index3 = np.array([1, 1])
# 配对:
# [(0 层 1 行 1 列),(1 层 2 行 1 列)]result = arr[index1,index2,index3]
print(result)
# [4 16]
http://www.lryc.cn/news/603424.html

相关文章:

  • 5.1 动⼿实现⼀个 LLaMA2 ⼤模型
  • Effective C++ 条款10:令operator=返回一个reference to *this
  • 【Java面试题】面向对象
  • Kubernetes 高级调度 01
  • 实现多路标注截图
  • WMS仓储管理系统在不良品管理中的优化策略
  • OpenCL - study - code04 canny
  • C++基础:模拟实现priority_queue(堆),详细介绍仿函数
  • Python 程序设计讲义(29):字符串的处理方法——大小写转换
  • 网络数据传输与NAT技术的工作原理
  • 计算机网络五层模型
  • 【微信小程序】12、生物认证能力
  • .gitignore 添加 vue.config.js 时不好使
  • 微信小程序无法构建npm,可能是如下几个原因
  • Excel批量加密工具,一键保护多个文件
  • 聚观早报 | 三星获特斯拉AI芯片订单;小米16首发成安卓最强SOC;iPhone 17 Pro支持8倍光学变焦
  • 递归推理树(RR-Tree)系统:构建认知推理的骨架结构
  • [leetcode] 实现 Trie (前缀树)
  • 开发避坑短篇(8):Java Cookie值非法字符异常分析与解决方案:IllegalArgumentException[32]
  • 【C#获取高精度时间】
  • 智能落地扇方案:青稞RISC-V电机 MCU一览
  • SZU大学物理实验报告|电位差计
  • 【dropdown组件填坑指南】—怎么实现下拉框的位置计算
  • python cli命令 cli工具命令 自定义cli命名 开发 兼容 window、mac、linux,调用示例
  • React面试题目和答案大全
  • 注册发送手机短信
  • Linux 完整删除 Systemd 服务的步骤
  • 【自制组件库】从零到一实现属于自己的 Vue3 组件库!!!
  • Rust 实战三 | HTTP 服务开发及 Web 框架推荐
  • leaflet中绘制轨迹线的大量轨迹点,解决大量 marker 绑定 tooltip 同时显示导致的性能问题