[PyTroch系列-17]:PyTorch基础 - 张量的索引与切片
Posted 文火冰糖的硅基工坊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[PyTroch系列-17]:PyTorch基础 - 张量的索引与切片相关的知识,希望对你有一定的参考价值。
作者主页(文火冰糖的硅基工坊):https://blog.csdn.net/HiWangWenBing
本文网址:https://blog.csdn.net/HiWangWenBing/article/details/119678906
目录
2.3 反向获取非连续的序列(保持原先顺序): 负数步长的使用
2.4 反/逆向获取非连续的序列(保持原先顺序): 负数步长的使用
第1章 张量的索引与切片
1.1 张量的维度方向
1.2 张量元素的访问:下标
张量元素的标识a[Idx-x][Idx-y][Idx-z]
其中Idx-x,Idx-y,Idx-z就是张量在不同维度方向的位置下标,代表了张量元素在整个张量空间中的位置。
1.3. 张量元素的下标切片
上述访问张量的方式称为下标访问,每次只能获取张量空间中的一个点。
如何访问张量空间中的多个顺序的元素呢?
这就涉及一个新的概念,张量下标索引的切片访问。
切片是针对某个维度方向下标访问的, 通过切片,一次可以访问多个顺序的元素,而不是唯一的元素。
每个维度方向上都可以进行各自独立的切片访问,最终可以得到的是分布在不同维度方向上的多个张量元素。
1.4 索引切片的表达方式:
[start : end : step]
通过三个参数和一个冒号“:”来定义切片的方式。
如下图所示:
(1)元素的下标索引
- 正数:正向编码,从开始第一元素开始编号,从0开始到正无穷, 0表示启第一个元素
- 负数:反向编码,从最后一个元素开始编号,从-1开始,到负无穷,-1表示最后一个元素
(2)步长:
- 正数:表示索引的增长方向是正向的。
- 负数:表示索引的增长方向是逆向的。
备注:Pytorch不支持负数步长,Tensorflow支持
(3)开闭区间
- start:是闭合区间,包含start索引的元素
- end:是开合区间,不包含end索引的元素
1.5 代码演示的前置条件
# 前置条件
import numpy as np
import torch
print("Hello World")
print(torch.__version__)
print(torch.cuda.is_available())
第2章 在一个维度方向上的切片操作(切片间通过冒号:分割)
2.1 正向获取连续的序列(保持原先顺序):默认步长为1
#代码示例:
print("原张量:")
a = torch.Tensor([0,1,2,3,4,5,6,7,8,9])
print(a)
print("\\n正向切片,正向定位:有冒号, 有起始 =>[start: end) 半闭半开区间")
#切取一段明确的、指定的、连续下标的元素序列
b = a[4] #没有冒号,取一个正向元素:起始闭合[4]
print(b)
b = a[6] #没有冒号,取一个正向元素:起始闭合[6]
print(b)
b = a[0:6] #有冒号,取正向序列[4,6) 半闭半开区间 => 起闭:a[4]和终开:a[5]
print(b)
输出结果:
原张量:
tensor([[ 0., 2., 4., 6., 8., 10.],
[ 1., 3., 5., 7., 9., 11.],
[12., 13., 14., 15., 16., 17.]])
在dim=0方向上切片,在dim=1方向省略(两个维度方向):
tensor([[ 1., 3., 5., 7., 9., 11.]])
在dim=0方向省略,在dim=1方向上切片(两个维度方向):
tensor([[ 2.],
[ 3.],
[13.]])
#代码示例2:
print("原张量:")
a = torch.Tensor([0,1,2,3,4,5,6,7,8,9])
print(a)
print("\\n正向切片,正向定位:有冒号, 有起始,无终止 =>[start:) 半闭半开区间")
b = a[5:] #有冒号,有起始,无终止,取正向序列:[5,-) 半开半闭区间
print(b)
输出:
原张量:
tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
正向切片,正向定位:有冒号, 有起始,无终止 =>[start:) 半闭半开区间
tensor([5., 6., 7., 8., 9.])
#代码示例3:
print("原张量:")
a = torch.Tensor([0,1,2,3,4,5,6,7,8,9])
print(a)
print("\\n正向切片,正向定位:有冒号, 无起始,无终止 =>[:) 半闭半开区间")
b = a[:] #有冒号,无起始,无终止,取正向序列:[0,-)半开半闭区间 或 [0,-1]全闭区间
print(b)
输出:
原张量:
tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
正向切片,正向定位:有冒号, 无起始,无终止 =>[:) 半闭半开区间
tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
代码示例4:
print("原张量:")
a = torch.Tensor([0,1,2,3,4,5,6,7,8,9])
print(a)
print("\\n正向切片,逆向定位:有冒号, 有起始 =>[start: end) 半闭半开区间")
b = a[-1] #没有冒号,取一个逆向元素:[10-1]
print(b)
b = a[-2] #没有冒号,取一个逆向元素:[10-2]
print(b)
b = a[-4:-1] #有冒号,有始有终,取[-4,-1)半开半闭区间元素序列。
print(b)
b = a[-4:] #有冒号,有始有终,取[-4,-)半开半闭区间元素序列。
print(b)
原张量:
tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
正向切片,逆向定位:有冒号, 有起始 =>[start: end) 半闭半开区间
tensor(9.)
tensor(8.)
tensor([6., 7., 8.])
tensor([6., 7., 8., 9.])
2.2 正向获取非连续的序列(保持原先顺序): 步长的使用
#代码示例1:
print("原张量:")
a = torch.Tensor([0,1,2,3,4,5,6,7,8,9])
print(a)
print("\\n正向切片,指定步长")
# 默认步长为1
b = a[2:8] #无步长冒号,默认为1
print(b)
b = a[2:8:] #有步长冒号,无步长数值,默认为1
print(b)
b = a[2:8:1] #有步长冒号,有步长数值:1
print(b)
b = a[2:8:2] #有步长冒号,有步长数值:2
print(b)
b = a[2:8:3] #有步长冒号,有步长数值:3
print(b)
输出:
原张量:
tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
正向切片,指定步长
tensor([2., 3., 4., 5., 6., 7.])
tensor([2., 3., 4., 5., 6., 7.])
tensor([2., 3., 4., 5., 6., 7.])
tensor([2., 4., 6.])
tensor([2., 5.])
#代码示例2:
print("原张量:")
a = torch.Tensor([0,1,2,3,4,5,6,7,8,9])
print(a)
print("\\n默认区间,默认步长")
b = a[:]
print(b)
b = a[::]
print(b)
b = a[::1]
print(b)
输出:
原张量:
tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
默认区间,默认步长
tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
2.3 反向获取非连续的序列(保持原先顺序): 负数步长的使用
Pytorch不支持
2.4 反/逆向获取非连续的序列(保持原先顺序): 负数步长的使用
Pytorch不支持
第3章 在多个维度方向上的切片操作(维度间通过逗号,分割)
#代码案例1:
print("原张量:")
a = torch.Tensor([[0,2,4,6,8,10],[1,3,5,7,9,11],[12,13,14,15,16,17]])
print(a)
print("\\n在dim=0的方向上切片:")
b = a[0]
print(b)
b = a[2]
print(b)
原张量:
tensor([[ 0., 2., 4., 6., 8., 10.],
[ 1., 3., 5., 7., 9., 11.],
[12., 13., 14., 15., 16., 17.]])
在dim=0的方向上切片:
tensor([ 0., 2., 4., 6., 8., 10.])
tensor([12., 13., 14., 15., 16., 17.])
# 代码案例2:
print("原张量:")
a = torch.Tensor([[0,2,4,6,8,10],[1,3,5,7,9,11],[12,13,14,15,16,17]])
print(a)
print("\\n在dim=0的方向上切片(一个维度方向):")
b = a[1:2]
print(b)
输出:
原张量:
tensor([[ 0., 2., 4., 6., 8., 10.],
[ 1., 3., 5., 7., 9., 11.],
[12., 13., 14., 15., 16., 17.]])
在dim=0的方向上切片(一个维度方向):
tensor([[ 1., 3., 5., 7., 9., 11.]])
#代码案例3:
print("原张量:")
a = torch.Tensor([[0,2,4,6,8,10],[1,3,5,7,9,11],[12,13,14,15,16,17]])
print(a)
print("\\n在dim=0和dim=1方向上切片(两个维度方向):")
b = a[1:2, 3:5]
print(b)
print("\\n在dim=0和dim=1方向上切片(两个维度方向):")
b = a[1:3, 3:5]
print(b)
输出:
原张量:
tensor([[ 0., 2., 4., 6., 8., 10.],
[ 1., 3., 5., 7., 9., 11.],
[12., 13., 14., 15., 16., 17.]])
在dim=0和dim=1方向上切片(两个维度方向):
tensor([[7., 9.]])
在dim=0和dim=1方向上切片(两个维度方向):
tensor([[ 7., 9.],
[15., 16.]])
第4章 对部分维度的自动推动(省略号...的使用)
#代码示例1:
print("原张量:")
a = torch.Tensor([[0,2,4,6,8,10],[1,3,5,7,9,11],[12,13,14,15,16,17]])
print(a)
print("\\n在dim=0方向上切片,在dim=1方向省略(两个维度方向):")
b = a[1:2, ...] # axis=0的切片为[1:2], axis=1省略,采用默认值
print(b)
print("\\n在dim=0方向省略,在dim=1方向上切片(两个维度方向):")
b = a[...,1:2,] # axis=0省略,axis=1的切片为[1:2], 采用默认值
print(b)
输出结果:
原张量:
tensor([[ 0., 2., 4., 6., 8., 10.],
[ 1., 3., 5., 7., 9., 11.],
[12., 13., 14., 15., 16., 17.]])
在dim=0方向上切片,在dim=1方向省略(两个维度方向):
tensor([[ 1., 3., 5., 7., 9., 11.]])
在dim=0方向省略,在dim=1方向上切片(两个维度方向):
tensor([[ 2.],
[ 3.],
[13.]])
作者主页(文火冰糖的硅基工坊):https://blog.csdn.net/HiWangWenBing
本文网址:https://blog.csdn.net/HiWangWenBing/article/details/119678906
以上是关于[PyTroch系列-17]:PyTorch基础 - 张量的索引与切片的主要内容,如果未能解决你的问题,请参考以下文章
[PyTroch系列-13]:PyTorch基础 - 张量的操作 - 筛选过滤
[PyTroch系列-7]:PyTorch基础 - 张量Tensor的算术运算
[PyTroch系列-5]:PyTorch基础 - 稀疏矩阵与其创建方法
[PyTroch系列-11]:PyTorch基础 - 张量Tensor元素的排序