3. 形状和转换

2023-11-18

形状和转换

array 大多数情况下都是以多维的形式出现的,一般对超过二维的多维 array 称为「张量」,二维矩阵,一维向量。因为多维度,所以自然而然地涉及到形状的改变和转换,可以算是张量最基础的「操作」了。

本节我们主要涉及以下三个方面:

  • 改变形状
  • 反序
  • 转置

其中,改变形状和转置都非常常用,我们建议您熟练掌握。

改变形状

⭐⭐⭐⭐⭐

这小节里面的 API 使用非常高频,尤其是扩展 1 维度的 expand_dims 和去除 1 维度的 squeeze,您未来会在很多神经网络架构中看到这俩货的身影。

⚠️ 需要注意的是:无论是扩展还是缩减,多或少的 shape 都是 1,squeeze 时如果指定维度,则该维度 shape 必须是 1。

# 换个整数的随机 array
rng = np.random.default_rng(seed=42)
arr = rng.integers(1, 100, (3, 4))
arr
array([[ 9, 77, 65, 44],
       [43, 86,  9, 70],
       [20, 10, 53, 97]])
# 有时候您可能需要将多维 array 打平
arr.ravel()
array([ 9, 77, 65, 44, 43, 86,  9, 70, 20, 10, 53, 97])
arr.shape
(3, 4)
np.expand_dims
#### 扩展 1 个维度,需要(必须)指定维度
# 其实就是多嵌套了一下
np.expand_dims(arr, 1).shape
(3, 1, 4)
# 扩充维度
expanded = np.expand_dims(arr, axis=(1, 3, 4))
expanded.shape
(3, 1, 4, 1, 1)
# 扩充维度不能跳跃
expanded = np.expand_dims(arr, axis=(1, 3, 8))
AxisError: axis 8 is out of bounds for array of dimension 5
np.squeeze
# squeeze 指定 axis 的shape必须为1
np.squeeze(expanded, axis=0)
ValueError: cannot select an axis to squeeze out which has size not equal to one
# 如果指定了维度,那就只会去除该维度,指定的维度必须为 1
np.squeeze(expanded, axis=1).shape
(3, 3, 1, 1)
# 去除所有维度为 1 的
np.squeeze(expanded).shape
(3, 3)
np.reshape/arr.reshape
# reshape 成另一个形状
# 也可以直接变为一维向量
arr.reshape(2, 2, 3)
array([[[ 9, 77, 65],
        [44, 43, 86]],

       [[ 9, 70, 20],
        [10, 53, 97]]])
# 可以偷懒,使用 -1 表示其他维度(此处 -1 为 3),注意,reshape 参数可以是 tuple 或连续整数
arr1 = arr.reshape((4, -1))
arr1
array([[ 9, 77, 65],
       [44, 43, 86],
       [ 9, 70, 20],
       [10, 53, 97]])
# 元素数量必须与原array一致
arr.reshape(3, 3)
ValueError: cannot reshape array of size 12 into shape (3,3)

# 另一种变换形状的方式 —— 原地变换
# 不过不能用-1
# 另外 resize 不一定和原来的元素数量一样多
arr2 = arr.resize((4, 3))
# 注意:上面的 reshape 会生成一个新的 array,但 resize 不会,所以我们需要用原变量名将它显示出来
# arr2 没有值
arr2
arr
array([[ 9, 77, 65],
       [44, 43, 86],
       [ 9, 70, 20],
       [10, 53, 97]])
# 直接 resize,如果元素数量多时会提示错误
arr.resize((2, 3))
ValueError: cannot resize an array that references or is referenced
by another array in this way.
Use the np.resize function or refcheck=False
# 可以copy一份
arrcopy = np.copy(arr)
arrcopy.resize((2, 3))
arrcopy
array([[ 9, 77, 65],
       [44, 43, 86]])
# arr 保持不变
arr
array([[ 9, 77, 65],
       [44, 43, 86],
       [ 9, 70, 20],
       [10, 53, 97]])
# 也可以将 refcheck 设为 False
# 此时 arr 会发生变化
# 元素数量超出时,截断;元素数量不够时,0填充
arr.resize((2,3), refcheck=False)
arr
array([[ 9, 77, 65],
       [44, 43, 86]])
arr.resize((3, 3), refcheck=False)
arr
array([[ 9, 77, 65],
       [44, 43, 86],
       [ 0,  0,  0]])
arr
array([[ 9, 77, 65],
       [44, 43, 86],
       [ 0,  0,  0]])
# 如果用 np.resize 会略有不同
# 元素数量不够时,会自动复制
np.resize(arr, (5, 3))
array([[ 9, 77, 65],
       [44, 43, 86],
       [ 0,  0,  0],
       [ 9, 77, 65],
       [44, 43, 86]])
# 元素数量多出来时,会自动截断
np.resize(arr, (2, 2))
array([[ 9, 77],
       [65, 44]])

反序

也可以看作是一种对原数组的转换,用的不多,可以了解一下,为接下来的索引和切片做个热身。

如果给一个字符串或数组让您反序,您可能会想到很多种方法,比如:reversed,或者写一个方法,或者用 Python list 的索引功能,而这也是 numpy 中 array 反序的方式。

# 字符串
s = "uevol"
s[::-1]
'loveu'
# 数组
lst = [1, "1", 5.2]
lst[::-1]
[5.2, '1', 1]
arr
array([[ 9, 77, 65],
       [44, 43, 86],
       [ 9, 70, 20],
       [10, 53, 97]])
arr
array([[ 9, 77, 65],
       [44, 43, 86],
       [ 9, 70, 20],
       [10, 53, 97]])
# 我们按上面的套路:默认列反序
arr[::-1]
array([[10, 53, 97],
       [ 9, 70, 20],
       [44, 43, 86],
       [ 9, 77, 65]])
# 列不变行反序
arr[::-1, :]
array([[10, 53, 97],
       [ 9, 70, 20],
       [44, 43, 86],
       [ 9, 77, 65]])
# 在不同维度上操作:行不变列反序
arr[:, ::-1]
array([[65, 77,  9],
       [86, 43, 44],
       [20, 70,  9],
       [97, 53, 10]])
# 行变列也变
arr[::-1, ::-1]
array([[97, 53, 10],
       [20, 70,  9],
       [86, 43, 44],
       [65, 77,  9]])

转置

⭐⭐⭐

转置是线性代数的基本操作,拿二维矩阵为例,通俗理解就是把它放倒,shape 反转,行变成列,列成为行。当然,对于多维也是类似的。我们建议您二维矩阵用 arr.T(会快很多),超过二维的张量可以用 np.transpose,会更加灵活些。

⚠️ 需要注意的是:一维数组转置还是自己。

# 一维
np.array([1,2]).T.shape
(2,1)
arr
array([[ 9, 77, 65],
       [44, 43, 86],
       [ 9, 70, 20],
       [10, 53, 97]])
arr.T
# 简便用法,把所有维度顺序都给倒过来
arr.T
array([[ 9, 44,  9, 10],
       [77, 43, 70, 53],
       [65, 86, 20, 97]])
# 将 shape=(1,1,3,4) 的转置后得到 shape=(4,3,1,1)
arr.reshape(1, 1, 3, 4).T.shape
(4, 3, 1, 1)
# 同上
arr.reshape(1, 2, 2, 1, 3, 1).T.shape
(1, 3, 1, 2, 2, 1)
np.transpose
# 这种转置方式可以指定 axes
np.transpose(arr)
array([[ 9, 44,  9, 10],
       [77, 43, 70, 53],
       [65, 86, 20, 97]])
# 不指定 axes 时和 .T 是一样的
np.transpose(arr.reshape(1, 2, 2, 1, 3, 1)).shape
(1, 3, 1, 2, 2, 1)
# 指定 axes,不过 axes 数量必须包含所有维度的序列
# 比如两个维度就是 (0, 1),四个就是 (0, 1, 2, 3)
# 当然,顺序可以改变,比如下面就是只转置第 2 个和第 3 个维度
# 注意,只有超过 2 维时,这样才有意义
# 下面的结果中,中间2个维度被调换顺序了,顺序就在axes中指定的
np.transpose(arr.reshape(1, 1, 3, 4), axes=(0, 2, 1, 3)).shape
(1, 3, 1, 4)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

3. 形状和转换 的相关文章

随机推荐

  • Java生成纳秒时间戳

    记一次生成高精度时间戳 类似与 net的时间戳 码着备忘 long timestamp System currentTimeMillis 1000000L System nanoTime 1000000L System currentTim
  • 函数的防抖与节流

    一 防抖与节流的联系 相同点 防抖 Debounce 和节流 Throttle 都是用来控制某个函数在一定时间内触发次数 两者都是为了减少触发频率 以便提高性能以及避免资源浪费 不同点 节流是第一个说了算 后续都会被节流阀屏蔽掉 防抖是最后
  • (小陈c语言)井字棋-初步实现以及改进方向

    作为小学上课偷偷和同桌在草稿本上玩的小游戏 井字棋 如今在电脑上也可以自己写出来玩 如图 不要惊讶 下面我们来看看怎么实现这个代码 正文开始 1 菜单界面 用多个printf 来打印即可 注意中间最好是空的不要连着字 void menu p
  • CVPR2020-RFANet-图像超分辨率新网络

    创新点都比较小 提升也很小 有种炒冷饭的感觉 论文地址 http openaccess thecvf com content CVPR 2020 papers Liu Residual Feature Aggregation Network
  • pycharm GIT 账号密码输入错误如何更改

    pycharm GIT 账号密码输入错误如何更改 第一次在pycharm中 输入git的账户或者密码出现错误 下一次pycharm系统会记住你输入错误的账户和密码 The requested URL returned error 500 只
  • python的日志logging模块使用总结

    文章转载与 http outofmemory cn code snippet 450 python rizhi logging module usage summary 1 简单的将日志打印到屏幕 import logging loggin
  • Android5——活动的生命周期方法

    1 活动的生命周期方法 onCreate 会在活动第一次被创建的时候使用 onStart 会在活动由不可见变为可见的时候调用 OnResume 会在活动准备好和用户进行交互的时候调用 此时的活动一定位于返回栈的栈顶 并且处于运行状态 onP
  • 简单两步解决Python的NLTK库DATA安装问题

    前言 本人使用Anaconda集成开发环境 已经安装有NLTK库 在使用NLTK最简单的分词功能时报错 查询错误 得知是没有安装NLTK的数据包 系统推荐使用以下命令 import nltk nltk download 用了之后弹出窗口 出
  • ROS 第四天 ROS中的关键组件

    1 Launch文件 通过XML文件实现多节点的配置和启动 可自动启动ROS Master
  • word文档中如何添加目录

    如果word文档的内容较多 结构复杂 那么在文档首页设置一个目录链接是非常有必要的 本文将介绍如何添加此目录 1 设置标题 在文档中选择将在目录中显示的内容 将之设置为 标题1 标题2 或 标题3 等 其中 标题1 代表一级标题 应为顶级目
  • 如何在 Java 中调用 MATLAB 代码

    文章目录 测评 完整源代码 运行环境 MATLAB R2022a Java 8 1 8 0 311 IntelliJ IDEA 2022 2 1 Ultimate Edition Maven 3 8 3 Windows 10 教育版 64位
  • ios 删除无用证书

    1 前往文件夹 Library MobileDevice Provisioning Profiles 然后可以删除里面的所有文件 然后就可以根据自己的需求重新下载了
  • STM32之_keil 编译内存大小解析

    Program Size Code 28784 RO data 6480 RW data 60 ZI data 3900 的含义 1 Code 程序所占用的FLASH大小 存储在FLASH 2 RO data Read only data
  • 简单的c++ UDP类 + 多线程 win32编程

    UdpClient h include Thread h class IUdpRecvCallback public virtual void OnRecv const char buf USHORT len const char from
  • 基恩士PLC KV8000+XH16EC总线控制,全ST程序实例

    基恩士PLC KV8000 XH16EC总线控制 全ST程序实例 本人自己开发全程序无加密 公司级框架 功能齐全 提供项目源码框架FB源码 触摸屏源码 需要一定ST基础才能看懂 重在分享编程思想 没用过该控制器的请慎拍 请使用11 10版本
  • 图像的二值化分割,otsu类间方差法

    二值化图像指图像中的每个像素只取两个离散的值之一 用数学公式表示为 公式中 f x y 表示一幅数字图像 X Y表示该图像中某像素的坐标值 T为 二值化的阈值 表示经过阈值运算后的二值化图像 这里0和1仅仅是一个抽象表示 并非实际像素值 它
  • python 实现百度关键字自动爬虫

    coding utf 8 In 3 import requests from lxml import etree import re from sqlalchemy import create engine engine create en
  • IDEA中快捷键大全

    Alt 回车 导入包 自动修正 Ctrl N 查找类 Ctrl Shift N 查找文件 Ctrl Alt L 格式化代码 Ctrl Alt O 优化导入的类和包 Alt Insert 生成代码 如get set方法 构造函数等 Ctrl
  • 【Linux】Linux下的自动化构建工具——make/makefile

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 一 make和makefile的区别 二 makefile
  • 3. 形状和转换

    文章目录 形状和转换 改变形状 np expand dims np squeeze np reshape arr reshape 反序 转置 arr T np transpose 形状和转换 array 大多数情况下都是以多维的形式出现的