numpy增加维度、删除维度的方法
作者:古明地盆 发布时间:2023-12-07 22:29:01
楔子
在 TensorFlow 中,可以给一个 tensor 增加一个维度、删除一个维度,那么在 Numpy 中该怎么呢?
删除维度、增加维度
先来看看如何增加一个维度:
import numpy as np
arr = np.array([[[1, 2, 3], [2, 3, 4]]])
print(arr)
"""
[[[1 2 3]
[2 3 4]]]
"""
print(arr.shape) # (1, 2, 3)
# 事实上第一个维度我们是不需要的,因为在该维度上数组的长度是 1
# 删除第 1 个维度,我们看到已经改变了
print(np.squeeze(arr, 0))
"""
[[1 2 3]
[2 3 4]]
"""
但是注意:只有数组长度在该维度上为 1,那么该维度才可以被删除。如果不是1,那么删除的话会报错。
import numpy as np
arr = np.array([[[1, 2, 3], [2, 3, 4]]])
print(arr.shape) # (1, 2, 3)
try:
# 删除第二个维度,显然在第二个维度上数组的长度是 2,不是 1
# 所以它不能被删除
print(np.squeeze(arr, 1))
except Exception as e:
print(e) # cannot select an axis to squeeze out which has size not equal to one
删除只能删除数组长度为 1 所对应的维度,同理添加也是添加一个维度也只是让数组在这个维度上的长度变成 1,因为数组本来不存在这个维度的,但是我们强行加上了一个维度,那么数组在这个维度上的长度只能是 1。
import numpy as np
arr = np.array([[1, 2, 3], [2, 3, 4]])
print(arr.shape) # (2, 3)
# 很好理解
print(np.expand_dims(arr, 0).shape) # (1, 2, 3)
print(np.expand_dims(arr, 1).shape) # (2, 1, 3)
print(np.expand_dims(arr, 2).shape) # (2, 3, 1)
arr = np.array([1, 2, 3])
print(np.expand_dims(arr, 0))
"""
[[1 2 3]]
"""
print(np.expand_dims(arr, 1))
"""
[[1]
[2]
[3]]
"""
以上就实现了数组维度的删除和增加,因为数组的元素是固定的,所以在删除维度和增加维度时,数组在该维度上的长度必须是 1。
另外,变化维度还可以使用 reshape,比如 arr 的维度是 (2, 1, 3),我们把第二个维度给去掉的话,那么直接 arr.reshape((2, 3)) 即可,增加维度也是同理,只要变化维度前后的元素个数不变即可。
import numpy as np
arr = np.array([[1, 2, 3], [2, 3, 4]])
print(arr.shape) # (2, 3)
arr1 = arr.reshape((2, 1, 1, 3))
print(arr1)
"""
[[[[1 2 3]]]
[[[2 3 4]]]]
"""
print(arr1.shape) # (2, 1, 1, 3)
print(np.all(arr1.reshape((2, 3)) == arr)) # True
最后,增加维度还有一种做法,但用的不多,举个栗子:
import numpy as np
arr = np.array([[1, 2, 3], [2, 3, 4]])
print(arr.shape) # (2, 3)
# 将维度变成 (2, 1, 3, 1, 1)
arr1 = arr[:, np.newaxis, :, np.newaxis, np.newaxis]
print(arr1.shape) # (2, 1, 3, 1, 1)
# np.newaxis 等价于 None
print(arr[:, None, :, None, None].shape) # (2, 1, 3, 1, 1)
# 使用 : 的部分和之前的维度是对应的,np.newaxis 或者 None 可以理解成 1
# 因此最终得到的数组的维度就是 (2, 1, 3, 1, 1)
# 再以一维数组为例
arr = np.array([1, 2, 3])
print(arr)
"""
[1 2 3]
"""
# 得到的数组的 shape 为 (1, 3)
print(arr[None, :])
"""
[[1 2 3]]
"""
# 得到的数组的 shape 为 (3, 1)
print(arr[:, None])
"""
[[1]
[2]
[3]]
"""
删除、增加一行或一列
说实话,改变数组的维度不是特别常见,更常见的是删除数组的一行或者一列,举个栗子:
# 原始数组
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
# 我们希望删除一行
[[ 0 1 2 3]
[ 8 9 10 11]]
# 或者删除一列
[[ 0 2 3]
[ 4 6 7]
[ 8 10 11]]
这种需求相对来说更加常见一些,那么应该怎么做呢?我们来看一下。
删除一行或一列
首先是删除:
import numpy as np
arr = np.arange(0, 12).reshape(3, 4)
print(arr)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
# 假设删除第二行
print(np.delete(arr, [1], axis=0))
"""
[[ 0 1 2 3]
[ 8 9 10 11]]
"""
# 删除第一行和第三行
print(np.delete(arr, [0, 2], axis=0))
"""
[[4 5 6 7]]
"""
# 删除前两行,slice(0, 2) 也可以换成 np.s_[0: 2]
print(np.delete(arr, slice(0, 2), axis=0))
"""
[[ 8 9 10 11]]
"""
删除列的话也是同理,只需要将 axis=0 换成 axis=1 即可,注意:如果不指定 axis 或者 axis 指定为 None,那么会 np.delete 会将传递的数组扁平化(变成一维数组),然后进行删除。举个栗子:
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
"""
[[1 2 3]
[4 5 6]]
"""
# 会将 arr 扁平化处理,然后删除索引为 1 的元素,因此要注意 axis 参数
print(np.delete(arr, [1]))
"""
[1 3 4 5 6]
"""
增加一行或一列
如果想增加一行或一列的话,要怎么做呢?
import numpy as np
arr = np.arange(0, 12).reshape(3, 4)
print(arr)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
# 在尾部增加一行,注意:这里的维度一定要匹配,指定 [0, 0, 0, 0] 是不行的,因为 arr 是一个二维数组
print(np.append(arr, [[0, 0, 0, 0]], axis=0))
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[ 0 0 0 0]]
"""
# 在尾部增加一列,维度同样要匹配
print(np.append(arr, [[0], [0], [0]], axis=1))
"""
[[ 0 1 2 3 0]
[ 4 5 6 7 0]
[ 8 9 10 11 0]]
"""
如果不指定 axis,那么仍然会将传递的数组扁平化,然后进行追加:
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
print(np.append(arr, 0)) # [1 2 3 4 5 6 0]
print(np.append(arr, [0, 0])) # [1 2 3 4 5 6 0 0]
print(np.append(arr, [[0, 0]])) # [1 2 3 4 5 6 0 0]
append 默认是在尾部进行追加,并且还要求维度要匹配,不是很方便。所以这里更推荐 insert 函数:
import numpy as np
arr = np.arange(0, 12).reshape(3, 4)
print(arr)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
# 索引为 1 的位置插入一行,值全为 0
print(np.insert(arr, 1, 0, axis=0))
"""
[[ 0 1 2 3]
[ 0 0 0 0]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
# 或者我们也可以手动指定
print(np.insert(arr, 1, [0, 0, 0, 0], axis=0))
"""
[[ 0 1 2 3]
[ 0 0 0 0]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
# 二维数组也是可以的
print(np.insert(arr, 1, [[0, 0, 0, 0], [0, 0, 0, 0]], axis=0))
"""
[[ 0 1 2 3]
[ 0 0 0 0]
[ 0 0 0 0]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
# 插入一列,注意元素个数要匹配,每一列是 3 个元素
print(np.insert(arr, 1, [[0, 0, 0], [0, 0, 0]], axis=1))
"""
[[ 0 0 0 1 2 3]
[ 4 0 0 5 6 7]
[ 8 0 0 9 10 11]]
"""
我们看到 insert 比 append 要方便很多,并且功能也更加强大一些,并且 append 完全可以使用 insert 实现,举个栗子:
import numpy as np
arr = np.arange(0, 12).reshape(3, 4)
print(arr)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
# 在尾部增加一行
print(np.insert(arr, arr.shape[0], 0, axis=0))
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[ 0 0 0 0]]
"""
# 在尾部增加一列
print(np.insert(arr, arr.shape[1], 0, axis=1))
"""
[[ 0 1 2 3 0]
[ 4 5 6 7 0]
[ 8 9 10 11 0]]
"""
最后,如果 insert 不指定维度,那么也是会先将数组扁平化,然后在进行 insert,举个栗子:
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(np.insert(arr, 1, [0, 0])) # [1 0 0 2 3 4 5 6]
总的来说还是比较简单的。
来源:https://www.cnblogs.com/traditional/p/12629050.html


猜你喜欢
- Python使用贪婪算法解决问题集合覆盖问题假设你办了个广播节目,要让全美50个州的听众都收听到。为此,你需要决定在哪些广播台播出。在每个广
- [摘要]了解如何充分利用SQL Server 2000的全文搜索功能。本文包含有关实现最大吞吐量和最佳性能的几点提示和技
- 本文实例讲述了JQuery中serialize()用法。分享给大家供大家参考。具体分析如下:一、serialize()定义和用法:seria
- 步骤查看历史记录# 查看历史记录git log -3实例Simba@SIMBA MINGW64 /t/IDE/IDEA/Workspace-
- 目录典型的函数装饰器叠放装饰器参数化装饰器标准库中的装饰器functools.wrapsfunctools.lru_cachefunctoo
- 1、用apt-get安装mysql#更新一下apt 仓库sudo apt-get update#安装mysql-servicesudo ap
- 本文实例为大家分享了python实现单链表反转的具体代码,供大家参考,具体内容如下代码如下:class Node(object): 
- 很多人都已经把 Javascript的用的炉火纯青了,但见到defer未必就知道他是做什么用的;很多人也都遇到过这样的问题,需要直接执行别且
- 1.两种查询引擎查询速度(myIsam 引擎 )InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from
- 1、安装Node.js,node.js安装包及源码下载地址为:https://nodejs.org/en/download/。2、安装npm
- 1.下载Python官网:传送门根据自己的主机环境下载python2.安装下载完后直接安装,安装时自定义安装路径,这里路径要记下来我的安装路
- 不知道大家在面试或者工作过程中有没有被 mouseover 和 mouseenter (对应的是 mouseout 和 mouseleave
- 1、效果图2、操作步骤File->Setting->Editor->File and TemplateIncludes/*
- 通常能听到的答案是使用了NULL值的列将会使索引失效,但是如果实际测试过一下,你就知道IS NULL会使用索引.所以上述说法有漏洞.着急的人
- 一、固定费用问题案例解析1.1、固定费用问题(Fixed cost problem)固定费用问题,是指求解生产成本最小问题时,总成本包括固定
- 如下所示:Uploadfiles = request.FILES.get('参数', '')for i in
- 写在前面当然这里说的百分百可能有点夸张,但其实想象一下,游戏里面的某个窗口的字符就是那种样子,不会变化的。而且识别的字符可能也不需要太多。中
- 1、通过url下载即后端提供文件的地址,直接使用浏览器去下载通过window.location.href = 文件路径下载window.lo
- 这个项目到一开始的kickoff到现在,持续了很长的一段时间,现在差不多也接近了尾声,所以要好好做个总结,下面不会设计到太多技术层面上的东西
- 限制访问可以基于某种权限,某些检查或者为login视图提供不同的位置,这些实现方式大致相同。一般的方法是直接在视图的 request.use