余晖落尽暮晚霞,黄昏迟暮远山寻
本站
当前位置:网站首页 > 编程知识 > 正文

Numpy的各种下标操作

xiyangw 2023-09-26 14:12 21 浏览 0 评论

目录

  • 技术背景
  • 二维矩阵的取法取单行和单个元素下标的list和tuple格式区分冒号的使用现存的list与numpy.array不相兼容的取法两个冒号的组合用法用None作扩维
  • 高维矩阵的取法
  • 总结概要
  • 版权声明

技术背景

本文所使用的Numpy版本为:Version: 1.20.3。基于Python和C++开发的Numpy一般被认为是Python中最好的Matlab替代品,其中最常见的就是各种Numpy矩阵类型的运算。对于矩阵的运算而言,取对轴和元素是至关重要的,这里我们来看看一些常见的Numpy下标取法和标记。

二维矩阵的取法

这里我们定义一个4*4的矩阵用于取下标,为了方便理解,这个矩阵中所有的元素都是不一样的:

In [1]: import numpy as np

In [2]: x = np.arange(16).reshape((4,4))

In [3]: x
Out[3]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

取单行和单个元素

比如我们想取第一行的所有元素,那么就是x[0],如果想取第一行的第一列的元素,那么就是x[0][0],而在numpy中为了简化,可以讲x[0][0]写成x[0,0]的形式:

In [4]: id = 0

In [5]: x[id]
Out[5]: array([0, 1, 2, 3])

In [6]: x[id][id]
Out[6]: 0

In [7]: x[id,id]
Out[7]: 0

下标的list和tuple格式区分

在上一个章节中我们提到的取单个元素x[0,0]的方法,其实本质上等同于x[(0,0)],也就是一个tuple的格式,但是如果把这里的tuple格式换成list,所表示的含义和得到的结果是完全不一样的:

In [8]: id = [1,1]

In [9]: x[id]
Out[9]: 
array([[4, 5, 6, 7],
       [4, 5, 6, 7]])

In [10]: x[id,id]
Out[10]: array([5, 5])

In [11]: id = (1,1)

In [12]: x[id]
Out[12]: 5

这里list格式的id,代表的意思是分别取第二行和第二行的内容,再放到一个完整的矩阵中。如果id设置为[1,2]的话,就是分别取第二行和第三行,而不是取第二行的第二个元素。如果需要取第二行的第二列的元素,那么还是需要用tuple的格式来取下标。有一个比较有意思的点是,如果把刚才的下标重复输入两次,也就是x[[1,2],[1,2]]的话,所表示的含义是分别取x[1][1]和x[2][2],再放到同一个矩阵中,也是一种比较常用的分离式取下标的方法。

冒号的使用

在Numpy的下标中,冒号和后置逗号同时出现,表示轴向全取,比如x[0,:]表示取x的第一行的所有数据,x[:,0]表示取第一列的所有数据:

In [14]: id = 1

In [15]: x[id,:]
Out[15]: array([4, 5, 6, 7])

In [16]: x[:,id]
Out[16]: array([ 1,  5,  9, 13])

现存的list与numpy.array不相兼容的取法

虽然上文我们提到,如果下标被定义成一个list格式的话,就表示分别取。但是目前Numpy的实现中还有这样的一个遗留问题,就是使用多维的list格式取下标,会自动将最外层转化成tuple的格式,采用tuple的取法。虽然计算时会给出告警,但是目前来说也需要引起一定的注意。

In [17]: id = [[1],[1]]

In [18]: x[id]
<ipython-input-18-23f8764f4b7e>:1: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
  x[id]
Out[18]: array([5])

In [19]: id = np.array([[1],[1]])

In [20]: x[id]
Out[20]: 
array([[[4, 5, 6, 7]],

       [[4, 5, 6, 7]]])

两个冒号的组合用法

在Numpy中冒号不与后置逗号同时出现时,表示的含义是从冒号前的元素取值到冒号后的元素,比如x[0:3]所表示的元素是[x[0],x[1],x[2]]。如果是两个冒号连用中间没有逗号的话,比如x[0:3:2],表示的是每隔2个元素取一个,最后得到的应该是[x[0],x[2]]。还有一种非常常见的操作是取[::-1]这样的下标,所表示的含义就是对当前轴进行倒序。

In [31]: x[::-1]
Out[31]: 
array([[12, 13, 14, 15],
       [ 8,  9, 10, 11],
       [ 4,  5,  6,  7],
       [ 0,  1,  2,  3]])

In [32]: x[::-1,::-1]
Out[32]: 
array([[15, 14, 13, 12],
       [11, 10,  9,  8],
       [ 7,  6,  5,  4],
       [ 3,  2,  1,  0]])

用None作扩维

虽然在Numpy中有broadcast和expand_dim之类的函数可以对矩阵进行扩维或者是广播,但是更方便的操作是对需要扩展的维度取一个None的下标,比如要把一个(4,4)大小的矩阵扩展成(1,4,4),那么就对下标取[None,:]或者[None,:,:]即可。而如果需要把(4,4)变成(4,1,4),那就需要把None换个位置为[:,None,:]就可以实现:

In [33]: x[None,:]
Out[33]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11],
        [12, 13, 14, 15]]])

In [34]: x[:,None,:]
Out[34]: 
array([[[ 0,  1,  2,  3]],

       [[ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11]],

       [[12, 13, 14, 15]]])

In [35]: x[:,:,None]
Out[35]: 
array([[[ 0],
        [ 1],
        [ 2],
        [ 3]],

       [[ 4],
        [ 5],
        [ 6],
        [ 7]],

       [[ 8],
        [ 9],
        [10],
        [11]],

       [[12],
        [13],
        [14],
        [15]]])

高维矩阵的取法

在高维矩阵中,因为没有了行和列这样的概念,因此需要从轴上去理解相关操作,我们先定义一个简单的三维张量:

In [49]: y = np.arange(32).reshape((2,4,4))

In [50]: y
Out[50]: 
array([[[ 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, 27],
        [28, 29, 30, 31]]])

常规的操作其实都跟前面章节中介绍二维张量一致,这里我们考虑一种比较特殊的场景。就是如果同样用二维矩阵的取法去取,只是第一条轴每个元素取一个id,比如取第0条轴的[0,1]元素和第1条轴的[2,3]元素,那么其实最简单的方案就是在第一个下标的位置加上一个位置元素,这个位置元素用下标id的第一个轴的长度去定义即可:

In [58]: id = np.array([[0,1],[2,3]])

In [59]: y[np.arange(id.shape[0]),id[:,0],id[:,1]]
Out[59]: array([ 1, 27])

总结概要

这篇文章的主要内容是梳理在Numpy中经常用到的各种取下标的操作,包括但不限于取指定轴的所有元素、取指定位置的单个元素、取指定位置的多个元素、扩维以及取未显式给定位置的多个元素等等。比较重要的是在Numpy中tuple的取法和list的取法是代表不一样的含义,并且由于历史原因,Numpy中存在一些list取法和numpy.array的取法表示不一致的地方,在本文中进行了总结。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/numpy-id.html

作者ID:DechinPhy

更多原著文章请参考:https://www.cnblogs.com/dechinphy/

打赏专用链接:https://www.cnblogs.com/dechinphy/gallery/image/379634.html

腾讯云专栏同步:https://cloud.tencent.com/developer/column/91958

相关推荐

华为交换机配置命令总结

1、配置文件相关命令[Quidway]displaycurrent-configuration显示当前生效的配置[Quidway]displaysaved-configuration显示fla...

解决账户无法登录的故障
解决账户无法登录的故障

在优化系统时错误地根据网上的提示,将唯一的Administrator账户设置为禁用,导致重启后无法进入系统。类似的故障还有使用组策略限制本地账户登录,导致重启后...

2023-10-11 17:16 xiyangw

S5720交换机登录提示初始密码存在安全风险
S5720交换机登录提示初始密码存在安全风险

问题描述客户每次登录输密码时,提示初始密码不安全,现在客户嫌麻烦想要去掉:Username:huaweiPassword:Warning:Theinitia...

2023-10-11 17:15 xiyangw

Springboot,Mybatis修改登录用户的密码
Springboot,Mybatis修改登录用户的密码

一、Mybatis.xml<updateid="changePassword"parameterType="string...

2023-10-11 17:15 xiyangw

PHP理论知识之沐浴更衣重看PHP基础(二)
PHP理论知识之沐浴更衣重看PHP基础(二)

接上篇,咱们继续讲解PHP基础八、标准PHP组件和框架的数量很多,随之产生的问题就是:单独开发的框架没有考虑到与其他框架的通信。这样对开发者和框架本身都是不利的...

2023-10-11 17:15 xiyangw

新鲜出炉UCloud云主机“数据方舟”评测报告(5)— — 关其城
新鲜出炉UCloud云主机“数据方舟”评测报告(5)— — 关其城

2015年10月29日,UCloud云主机黑科技——“数据方舟”功能正式上线,首轮内测随即开放。截止至2015年12月6日,我们共收到了534位用户的评测申...

2023-10-11 17:14 xiyangw

业余无线电Q简语及英文缩语
业余无线电Q简语及英文缩语

Q简语:语音通信及CW通信通用(加粗为常用)QRA电台何台QRB电台间之距离QRG告之正确频率QRH频率是否变动QRI发送音调QRJ能否收到QRK信号之可...

2023-10-11 17:14 xiyangw

非常详细!如何理解表格存储的多版本、生命周期和有效版本偏差
非常详细!如何理解表格存储的多版本、生命周期和有效版本偏差

表格存储在8月份推出了容量型实例,直接支持了表级别最大版本号和生命周期,高性能实例也将会在9月中旬支持这两个特性。那么,最大版本号和生命周期以及特有的...

2023-10-11 17:14 xiyangw

H3C交换机恢复出厂和各种基本配置,这20个要点你知道吗?
H3C交换机恢复出厂和各种基本配置,这20个要点你知道吗?

私信“干货”二字,即可领取138G伺服与机器人专属及电控资料!H3C交换机不知道密码如何恢复出厂设置1、开机启动,Ctrl+B进入bootrom菜单,选择恢复出...

2023-10-11 17:13 xiyangw

在使用移动支付系统的时候如何保护信息安全?

移动支付的方式近年来不断被更新,使得Venmo(据嘉丰瑞德理财师了解,此为美国的“支付宝”)之类的支付方式已经可以某种意义上代替随身携带现金了。但是你必须防范那些第三方应用程序轻松地获取你的银行卡以及...

界面控件DevExpress WinForms MVVM入门指南——登录表单(下)

从本文档中,您将了解如何向应用程序添加登录表单。在本节教程中着重讨论了如何实现此任务,这基本上是附加应用程序功能的一部分。DevExpressUniversalSubscription官方最新版免...

linux基础命令(一)
linux基础命令(一)

为啥要学linux?您可能熟悉WindowsXP、Windows7、Windows10和MacOSX等操作系统。Linux就是这样一种强大的操...

2023-10-11 17:13 xiyangw

MySQL数据库密码忘记了,怎么办?

#头条创作挑战赛#MySQL数据库密码忘记了且没有其他可以修改账号密码的账户时怎么办呢?登录MySQL,密码输入错误/*密码错误,报如下错误*/[root@TESTDB~]#mysql-u...

MobaXterm忘记Session密码,如何查看已保存的密码
MobaXterm忘记Session密码,如何查看已保存的密码

MobaXterm工具登录过SSH终端后,如果存储了Session(存储后再连接ssh的时候只需要输入账号不需要输入密码就可以直接连接上ssh),则可以...

2023-10-11 17:12 xiyangw

华为交换机密码丢失修改方法
华为交换机密码丢失修改方法

华为S2300交换机找回密码设置一、目的交换机的console和telnet密码丢失,无法登录设备。交换机已进行过数据配置,要把密码恢复而数据配置不能丢失。二、...

2023-10-11 17:12 xiyangw

取消回复欢迎 发表评论: