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

NumPy 2.x 完全指南【十】基础索引

文章目录

  • 1. 原生 Python 中的基础索引和切片
    • 1.1 基础索引
    • 1.2 切片
  • 2. NumPy 基础索引
    • 2.1 只使用索引序号
    • 2.2 切片

1. 原生 Python 中的基础索引和切片

在原生 Python 中,可以直接使用索引(Index)来访问序列(列表、元组、字符串等)中的元素。

支持两种类型的索引:

  • 正索引:从左到右,从 0 开始,到(序列长度-1)结束
  • 负索引:从右到左,从 -1 开始,到( -序列长度) 结束

在这里插入图片描述

支持以下两种使用方式:

  • 基础索引
  • 切片

1.1 基础索引

基础索引也称为简单索引或直接索引,是指通过索引序号直接访问序列中的元素。

基础语法:

sequence[index]

其中:

  • sequence: 支持索引操作的数据类型,如列表、元组、字符串等。
  • index: 整数,表示元素的位置。

示例 1 ,通过索引访问列表、字符串中的元素:

# 正索引
# 一维列表
arr1d = [1, 2, 3, 4, 5]
# 访问第 2 个元素 → 2
print(arr1d[1])# 字符串
str_name = "Donald Trump"
# 访问第 3 个元素 → n
print(str_name[2])# 负索引
# 访问倒数第 2 个元素 → 4
print(arr1d[-2])
# 访问倒数第 3 个元素 → u
print(str_name[-3])

示例 2 ,对于嵌套列表,可以使用多个中括号 [](链式索引) :

# 二维(3 x 3)
arr2d = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]
# 访问第 2 行 → [4, 5, 6]
print(arr2d[1])
# 访问第 2 行、第 3 列 → 6
print(arr2d[1][2])# 三维(2 x 3 x 3)
arr3d = [[[1, 2, 3],[4, 5, 6],[7, 8, 9]],[[10, 11, 12],[13, 14, 15],[16, 17, 18]]]
# 访问第 1 层、第 2 行 → [4, 5, 6]
print(arr3d[0][1])
# 访问第 1 层、第 2 行、第 3 列 → 6
print(arr3d[0][1][2])

1.2 切片

切片(Slicing) 是一种通过指定起始、终止位置和步长来获取序列类型(如列表、字符串、元组等)子集的操作。

基本语法:

sequence[start : end : step]

参数说明:

  • start:起始索引(包含该位置元素),指定切片的起始位置,默认为 0
  • end:结束索引(不包含该位置元素),指定切片的结束位置,默认到序列末尾结束。
  • step:步长,控制元素选取的间隔方向和步幅,支持正数(从左向右选取)和负数(从右向左选取),默认为 1

示例 1 ,一维的嵌套列表:

arr = [0, 1, 2, 3, 4]
print(arr[::2])    # [0, 2, 4](步长2,正向)
print(arr[::-1])   # [4, 3, 2, 1, 0](反向)
print(arr[3:0:-1]) # [3, 2, 1](反向,start=3, end=0)

对于二维及以上的 Python 原生嵌套列表,无法直接进行多个维度的切片操作。当尝试使用 [] 进行多维切片时,只能访问到第一个维度的元素,而无法同时处理多个维度。

示例 2 ,单个 [] 时表示在第一个维度进行切片:

# 二维(3 x 3)
arr2d = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]
# 第一行和第三行
print(arr2d[0::2])
# 输出: [[1, 2, 3],
#       [7, 8, 9]]

示例 3 ,单个 [] 输入多个维度时不支持:

# 期望:
# 行方向:第一行和第三行,列方向:第一列和第三列
print(arr2d[0::2,0::2])
# 报错: TypeError: list indices must be integers or slices, not tuple

示例 4 ,多个 [] 时并不是依次对每个维度进行切片操作,始终都只能在第一个维度上执行操作:

# 期望:先选择第一行和第三行,再选择第一列和第三列
# 期望输出:
# [[1 3]
#  [7 9]]
print(arr2d[0::2][0::2])  # 实际输出: [[1, 2, 3]] ,先选择第一行和第三行(剩两行),再选择第一行和第三行(剩一行)# 三维(2 x 3 x 3)
arr3d = [[[1, 2, 3],[4, 5, 6],[7, 8, 9]],[[10, 11, 12],[13, 14, 15],[16, 17, 18]]]
# 期望:先第一层和第三层,再第一行和第三行,最后第一列和第三列
# 期望输出:
# [[[1 3]
#   [7 9]]]
print(arr3d[0::2][0::2][0::2]) #  实际输出: [[[1, 2, 3], [4, 5, 6], [7, 8, 9]]] ,先选择第一层和第三层(只有第一层),之后都是选择第一层

示例 5 ,sequence[:]sequence[::] 表示完整切片(全切),等价于 sequence[0:len(sequence):1]

arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# 全切:选择所有行和所有列
print(arr[::])

2. NumPy 基础索引

NumPy 数组支持比 Python 原生列表更强大的索引功能,根据索引对象的类型划分了三种方式:

  • 基础索引:只使用索引序号或切片。
  • 高级索引:使用整数数组或布尔数组。
  • 字段访问:通过字段名访问(结构化数组)。

注意:基础索引包含了原生 Python 中的基础索引和切片,并支持多维操作。

2.1 只使用索引序号

与原生 Python 序列类型一样,使用中括号加下标([index])的方式,返回的是原数组的视图(View),对索引结果的修改会直接影响原数组,也支持正负索引。

索引规则

  • 每个 [] 对应一个维度的操作
  • 索引顺序从外到内
  • 未指定的维度默认包含所有元素

示例 1 ,使用 [index] 获取单个元素:

# 一维数组
arr1d = np.array([1, 2, 3, 4, 5])
# 访问第 2 个元素 → 2
print(arr1d[1])# 二维数组(3 x 3)
arr2d = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
# 访问第 2 行、第 3 列 → 6
print(arr2d[1][2])# 三维数组(2 x 3 x 3)
arr3d = np.array([[[1, 2, 3],[4, 5, 6],[7, 8, 9]],[[10, 11, 12],[13, 14, 15],[16, 17, 18]]])
# 访问第 1 层、第 2 行、第 3 列 → 6
print(arr3d[0][1][2])

上面案例中对于多维数组的索引操作,我们使用了多个中括号([]),将每个维度的索引分别按照维度顺序(从 0 轴开始)放在各自的方括号中,例如一个三维数组 arr[0][1][2]) 表示:

  • [0]:第一个轴(最外层)上的第 0 个(定位到二维数组)。
  • [1]:第二个轴(中层)上的第 1 个(定位到行)。
  • [2]:第三个轴(最内层)上的第 2 个(定位到行的第几列)。

示例 2 ,当 [] 数量小于轴数时,未指定的维度默认包含所有元素 :

# 第一层
print(arr3d[0]) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# 第一层第二行
print(arr3d[0][1]) # [4, 5, 6]

以上使用方式和原生 Python 一致,此外 NumPy 还支持使用一个中括号将多个维度的索引放在一个中括号中,即支持以下两种表达式:

  • arr[i][j]...[k]:使用多个中括号
  • arr[i,j...k]:使用一个中括号(推荐)

示例 3 ,使用一个中括号操作三维数组:

# 第一层
print(arr3d[0])  # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# 第一层第二行
print(arr3d[0, 1])  # [4, 5, 6]
# 第一层第二行第三列
print(arr3d[0, 1, 2])  # 6

2.2 切片

NumPy 切片语法将原生 Python 的切片概念扩展到多维数组,基本语法:

arr[start:end:step, start:end:step, ...]

注意事项:

  • 使用多个 [] 时和原生 Python 一样,只能在第一个维度上进行操作。
  • 使用逗号分隔不同维度,顺序对应数组的轴(从 0 开始),每个维度都遵循 start:end:step 规则。
  • 未指定的维度默认包含所有元素。
  • 支持负索引和自动越界处理。
  • 生成的所有数组始终是原数组的视图,与原数组共享数据内存,修改视图会影响原数组。
  • 从大数组中提取切片时需要特别小心,因为提取的小部分包含对原大数组的引用,而大数组的内存不会被释放,直到所有派生的数组都被垃圾回收。

示例 1 ,一维数组:

arr1d = np.array([1, 2, 3, 4, 5])
# 索引区间: [1,4)
print(arr1d[1:4])     # [2 3 4]
# 开始、结束默认值,步长为 2
print(arr1d[::2])     # [1 3 5]
# 负索引,步长为 1(反向)
print(arr1d[::-1])    # [5 4 3 2 1]

二维数组的形状为【行 x 列】 ,则切片格式为 arr[start:end:step, start:end:step] (其他维度的数组,参考二维进行类推即可):

  • 第一个参数:对行进行操作
  • 第二个参数:对列进行操作

示例 2 ,二维数组:

arr2d = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])# 先取所有行,再取第 2 列:
print(arr2d[:, 1]) #  [2, 5, 8]
# 取第 2 行到末尾,再取第 2 列到末尾
print(arr2d[1:, 1:]) # [[5, 6], [8, 9]]
# 先每隔一行取一次,再取所有列
print(arr2d[::2, :]) # [[1, 2, 3], [7, 8, 9]]

示例 3 ,三维数组:

arr3d = np.array([[[1, 2, 3], [4, 5, 6], [7, 8, 9]],[[10, 11, 12], [13, 14, 15], [16, 17, 18]]
])# 取第 1 层,所有行,第 2 到 3 列
print(arr3d[0, :, 1:3]) #  [[2 3]  [5 6]  [8 9]]# 取所有层,第 2 行,第 1 列
print(arr3d[:, 1, 0]) #  [ 4 13]

示例 4 ,未指定的维度默认包含所有元素 :

# 第 1 、3 层的所有行所有列
print(arr3d[::2])
# [[[1 2 3]
#   [4 5 6]
#   [7 8 9]]]# 第 1 、3 层,再第 1 、3 行的所有列
print(arr3d[::2, ::2])
# [[[1 2 3]
#   [7 8 9]]]

示例 5 ,可以使用冒号(:)或(::)显式的指定某个维度的全部元素:

# 二维数组:
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 取所有元素
print(arr[::, ::])
# 等价写法:print(arr[:, :]) print(arr[:])
# 输出:
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]# 取所有行,第 1、2 列
print(arr[::, :2:1])

示例 6 ,除此之外,NumPy 还支持使用省略号(Ellipsis)进行自动扩展,隐式补全所有未指定的维度,进一步简化操作:

# 三维数组
arr_3d = np.arange(24).reshape(2, 3, 4)  # 形状 (2,3,4)# 全切:所有元素
print(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]]]# 所有层、所有行、第 1、2 列
print(arr_3d[..., 0:2:1])
# [[[ 0  1]
#   [ 4  5]
#   [ 8  9]]
#
#  [[12 13]
#   [16 17]
#   [20 21]]]

注意,一个数组只能写一个省略号,多个会报错 IndexError

arr_3d[..., 0,...,]   # IndexError: an index can only have a single ellipsis ('...')

相关文章:

  • 网络协议与系统架构分析实战:工具与方法全解
  • 五大静态博客框架对比:Hugo、Hexo、VuePress、MkDocs、Jekyll
  • 聊天项目总结
  • 多边形,矩形,长方体设置
  • livenessProbe 和 readinessProbe 最佳实践
  • 函数加密(Functional Encryption)简介
  • Postgresql与openguass对比
  • WiFi密码查看器打开软件自动获取数据
  • 开发者版 ONLYOFFICE 协作空间:3.1版本 API 更新
  • 视频编解码学习十一之视频原始数据
  • Redis扫盲
  • Unity 2D 行走动画示例工程手动构建教程-AI变成配额前端UI-完美游戏开发流程
  • 亚马逊云科技:引领数字时代的云服务先锋
  • 汉得 x 真味生物|H-ZERO PaaS项目启动,共启数字化新征程!
  • 模板的使用
  • 【LUT技术专题】SPFLUT代码解读
  • 捌拾肆- 量子傅里叶变换 (2)
  • 机器学习中分类模型的常用评价指标
  • echarts按需加载和不按需加载,打包后的具体对比
  • 网站开发过程中样式忽然不显示问题
  • 5吨煤炭“瞬间蒸发”?掺水炭致企业损失千万,腐败窝案曝光
  • 上海杨浦:鼓励龙头企业与高校共建创新联合体,最高支持200万元
  • 耗资10亿潮汕豪宅“英之园”将强拆?区政府:非法占用集体土地
  • A股三大股指涨跌互现:银行股领涨,两市成交12915亿元
  • 日本广岛大学一处拆迁工地发现疑似未爆弹
  • 云南威信麟凤镇通报“有人穿‘警察’字样雨衣参与丧事”:已立案查处