技术背景

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

二维矩阵的取法

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

In [1]: import numpy as npIn [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 = 0In [5]: x[id]
Out[5]: array([0, 1, 2, 3])In [6]: x[id][id]
Out[6]: 0In [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 = 1In [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

Numpy的各种下标操作相关推荐

  1. Python Numpy中返回下标操作函数-节约时间的利器

    如果觉得Python慢,那么首先应该想到是不是没有用对. Numpy是Python中自带的一个数值计算库,包含了大量数值计算的常用方法.其底层大量使用C/C++(超过50%的代码量),矩阵计算调用LA ...

  2. numpy和torch数据操作对比

    对numpy和torch数据操作进行对比,避免遗忘. ndarray和tensor import torch import numpy as npnp_data = np.arange(6).resh ...

  3. 【C 语言】数组 ( 数组取值操作 | array[i][j] 用法 等价于 *( *(array = i) + j ) 用法 | 下标操作到指针操作演化过程 )

    文章目录 一.数组取值操作方法 二.一维数组取值 下标操作到指针操作 演化过程 三.二维数组取值 下标操作到指针操作 演化过程 一.数组取值操作方法 给定一个二维数组 : int array[2][3 ...

  4. 【C 语言】字符串操作 ( 使用 数组下标 操作字符串 | 使用 char * 指针 操作字符串 )

    文章目录 一.使用 数组下标 或 指针 操作字符串 1.使用 数组下标 操作字符串 2.使用 char * 指针 操作字符串 二.代码示例 一.使用 数组下标 或 指针 操作字符串 1.使用 数组下标 ...

  5. C++语言map和unordered_map的下标操作

    C++语言map和unordered_map的下标操作 C++语言map和unordered_map的下标操作

  6. 关于map的下标操作的2个例子

    #include <iostream> #include <map> #include <set> #include <string> using na ...

  7. Python 列表下标操作

    Python  列表下标操作 引用网址: https://www.jianshu.com/p/a98e935e4d46 转载于:https://www.cnblogs.com/zenghanxi/p/ ...

  8. numpy.polynomial 常见多项式操作

    numpy.polynomial 常见多项式操作 文章目录 构造一元多项式 多项式与数直接相乘和加减 快速求某点处的值 poly1d 的 attributes poly1d 的 Methods 积分 ...

  9. 2 NumPy库的基础操作

    NumPy是一个专门用来进行数学计算的第三方库,对线性代数的支持较好.(Matlab与Python一较高下?期待...) 2.1 NumPy库安装和基本方法 安装好pip后,在cmd窗口输入:pip ...

  10. Python基础 NumPy数组相关概念及操作

    NumPy是Python的一种开源的数值计算扩展库,提供 数组支持以及相应的高效处理函数,它包含很多功能,如创建n维数组()矩阵,对数组进行函数运算,数值积分,线性代数计算,傅里叶变换和随机数产生等. ...

最新文章

  1. 适合初学者的java书籍
  2. 一道看完答案你会觉得很沙雕的「动态规划算法题」
  3. linux usb驱动
  4. SpringMVC之拦截器和异常处理
  5. I had no sooner finished eating than went to toilet.
  6. python行数最短的PCA实现方式
  7. 使用 Flomesh 强化 Spring Cloud 服务治理
  8. 忆当年!董明珠处罚困难员工后自掏腰包补偿:制度必须坚决执行
  9. hibernate入门学习(更新中)
  10. Mac很好用的音乐转换器:NoteBurner Spotify Music Converter mac
  11. Vue-动态绑定属性
  12. VB2010(18)_各种对话框的使用
  13. 集中化Linux日志管理系统
  14. 基于php的在线问卷调查系统
  15. 如何用LaTeX写简历
  16. 第二人生的源码分析(十四)人物角色的实现
  17. 民生服务是“双创”永恒主题 且听“鸿雁旅居网”、“熊猫中医”谈背后心路历程...
  18. lae界面开发工具入门之介绍七--组件篇-文本篇
  19. 聚合型代码审计工具QingScan使用实践
  20. Warning[Pe069]: integer conversion resulted in truncation

热门文章

  1. 【贤者之路】Python/c Api 扩展解析
  2. 深刻对比一下阿里云服务器和腾讯云服务器的优劣和区别
  3. 万维网联盟(W3C)创立了 WWW 标准
  4. 程序物语(八):我心戚戚
  5. 电子科技大学关于佛系青年的社会实践调查
  6. kotlin遍历数据同时删除之利用kotlin迭代器安全删除
  7. 检查压缩包是否损坏_【安全知识】运动安全带检查PPE(个人防护装备)检查程序与表格...
  8. python 类调用不存在的方法_找不到Python方法,但在类中定义
  9. 后门防御阅读笔记,Black-box Detection of Backdoor Attacks with Limited Information and Data
  10. 字节跳动(今日头条)小程序支付、支付宝、微信支付完整版