NumPy 基本切片和索引的具体使用方法


Posted in Python onApril 24, 2019

索引和切片是NumPy中最重要最常用的操作。熟练使用NumPy切片操作是数据处理和机器学习的前提,所以一定要掌握好。

文档:https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html

索引

ndarrays可以使用标准Python x[obj]语法对其进行索引 ,其中x是数组,obj是选择方式。有三种可用的索引:字段访问,基本切片,高级索引。究竟是哪一个取决于obj。

注意
在Python中,x[(exp1, exp2, ..., expN)]相当于 x[exp1, exp2, ..., expN]; 后者只是前者的语法糖。

基本切片和索引

基本切片将 Python 的切片基本概念扩展到 N 维。当obj是一个slice对象(由括号内的start:stop:step符号构造)、整数或切片对象和整数的元组时,会发生基本切片。也包括省略号(三个点)和newaxis对象。

从版本1.15.0开始不推荐使用:为了保持向后兼容Numeric中的常见用法,如果选择对象是包含 slice 对象、省略号,或 newaxis 对象的任何非 nararray 和非元组序列(例如 list),则也会启动基本切片,但不适用于整数数组或其他嵌入序列。

使用 N 个整数进行索引的最简单情况返回表示相应项的数组标量。正如在 Python 中,所有下标是从零开始:对我个索引你,取值范围为

0≤ni<di

其中d_i是 我的阵列的形状的个元素。负指数被解释为从数组的末尾开始计数(即,如果 n_i <0,则意味着n_i + d_i)。

基本切片生成的所有数组始终 是原始数组的视图。

序列切片的标准规则适用于基于每维的基本切片(包括使用步骤索引)。要记住的一些有用的概念包括:

基本切片语法是i:j:k其中我是起始索引, j是停止索引,并且ķ是步骤

k≠0

这将选择米元件(在对应的尺寸)与索引值我,i,i+k,...,1 +(m - 1)k, 其中

m=q+(r neq0)

和 q 和 r 是通过j-i 除 k 所获得的商和余数:

j−i=qk+r

,因此

i+(m−1)k<j

>>>
>>> x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> x[1:7:2]
array([1, 3, 5])

负i和j被解释为n + i和n + j,其中 n是相应维度中的元素数量。负k使得踩踏指向更小的指数。

>>>
>>> x[-2:10]
array([8, 9])
>>> x[-3:3:-1]
array([7, 6, 5, 4])

假设n是要切片的维度中的元素数。然后,如果我没有给出其默认值为0 K> 0和 N - 1为ķ<0 。如果没有给出j,则对于k> 0 ,默认为n ; 对于k <0,默认为-n-1。如果没有给出k,则默认为1.注意, 与此相同,表示沿此轴选择所有索引。:::

>>>
>>> x[5:]
array([5, 6, 7, 8, 9])

如果选择元组中的对象数小于 N,则:假定任何后续维。

>>>
>>> x = np.array([[[1],[2],[3]], [[4],[5],[6]]])
>>> x.shape
(2, 3, 1)
>>> x[1:2]
array([[[4],[5],[6]]])

Ellipsis扩展为:制作与长度相同的选择元组所需的对象数x.ndim。可能只存在一个省略号。

>>>
>>> x[...,0]
array([[1, 2, 3],
    [4, 5, 6]])

newaxis选择元组中的每个对象用于将所得选择的维度扩展一个单位长度维度。添加的维度是newaxis 对象在选择元组中的位置。

>>>
>>> x[:,np.newaxis,:,:].shape
(2, 1, 3, 1)

整数i返回相同的值,i:i+1 除了返回的对象的维度减少1.特别是,具有第p个元素的整数(和所有其他条目:)的选择元组返回具有维度的相应子数组N - 1。如果N = 1, 则返回的对象是数组标量。Scalars中解释了这些对象。

如果选择元组具有:除作为切片对象的第p个条目之外的 所有条目i:j:k,则返回的数组具有通过连接由元素i,i + k,...,i +的整数索引返回的子数组形成的维N. m - 1)k <j,

:切片元组中具有多个非条目的基本切片,就像使用单个非:条目重复应用切片一样,其中:连续地获取非条目(所有其他非:条目被替换:)。因此, 在基本切片下的x[ind1,...,ind2,:]行为xind1。

警告

对于高级索引,上述情况并非如此。

您可以使用切片来设置数组中的值,但是(与列表不同)您永远不会增长数组。要设置的值的大小 必须(可广播)为与其相同的形状 。x[obj] = valuex[obj]

注意

请记住,切片元组总是可以构造为obj 并在x[obj]符号中使用。可以在构造中使用切片对象来代替[start:stop:step] 符号。例如,x[1:10:5,::-1]也可以实现为。这对于构造适用于任意维数组的通用代码非常有用。obj = (slice(1,10,5), slice(None,None,-1)); x[obj]

numpy.newaxis
该newaxis对象可用于所有切片操作,以创建长度为1的轴。newaxis是'None'的别名,'None'可以用来代替相同的结果。

高级索引

当选择对象obj是非元组序列对象,ndarray(数据类型为整数或bool)或具有至少一个序列对象或ndarray(数据类型为integer或bool)的元组时,将触发高级索引。高级索引有两种类型:整数和布尔值。

高级索引始终返回数据的副本(与返回视图的基本切片形成对比)。

警告

高级索引的定义意味着x[(1,2,3),]根本不同于x[(1,2,3)]。后者相当于x[1,2,3]触发基本选择,而前者将触发高级索引。一定要明白为什么会这样。

同时认识到x[[1,2,3]]将触发高级索引,而由于上面提到的不推荐的数字兼容性, x[[1,2,slice(None)]]将触发基本切片。

整数数组索引

整数数组索引允许根据数组的N维索引选择数组中的任意项。每个整数数组表示该维度的许多索引。

纯整数数组索引

当索引包含尽可能多的整数数组时,索引的数组具有维度,索引是直接的,但与切片不同。

高级索引始终作为一个广播和迭代:

result[i_1, ..., i_M] == x[ind_1[i_1, ..., i_M], ind_2[i_1, ..., i_M],
              ..., ind_N[i_1, ..., i_M]]

请注意,结果形状与(广播)索引数组形状相同。ind_1, ..., ind_N


从每一行开始,应选择一个特定元素。行索引是just ,列索引指定要为相应行选择的元素。将两者结合使用可以使用高级索引解决任务:0, 1, 2

>>>
>>> x = np.array([[1, 2], [3, 4], [5, 6]])
>>> x[[0, 1, 2], [0, 1, 0]]
array([1, 4, 5])

为了实现类似于上面的基本切片的行为,可以使用广播。该功能ix_可以帮助这种广播。通过示例可以最好地理解这一点。


从4x3阵列中,应使用高级索引选择角元素。因此,列是其中之一的所有元素和行是需要选择的行。要使用高级索引,需要明确选择所有元素。使用前面解释的方法可以写:0, 2

>>>
>>> x = array([[ 0, 1, 2],
...      [ 3, 4, 5],
...      [ 6, 7, 8],
...      [ 9, 10, 11]])
>>> rows = np.array([[0, 0],
...         [3, 3]], dtype=np.intp)
>>> columns = np.array([[0, 2],
...           [0, 2]], dtype=np.intp)
>>> x[rows, columns]
array([[ 0, 2],
    [ 9, 11]])

但是,由于上面的索引数组只是重复自身,因此可以使用广播(比较诸如此类的操作 )来简化:rows[:, np.newaxis] + columns

>>>
>>> rows = np.array([0, 3], dtype=np.intp)
>>> columns = np.array([0, 2], dtype=np.intp)
>>> rows[:, np.newaxis]
array([[0],
    [3]])
>>> x[rows[:, np.newaxis], columns]
array([[ 0, 2],
    [ 9, 11]])

这种广播也可以使用以下功能实现ix_:

>>>
>>> x[np.ix_(rows, columns)]
array([[ 0, 2],
    [ 9, 11]])

请注意,如果没有np.ix_调用,只会选择对角线元素,如上例所示。对于使用多个高级索引进行索引,这个差异是最重要的。

结合高级索引和基本索引

当至少有一个slice(:),省略号(...)或newaxis 索引(或者数组的维度多于高级索引)时,行为可能会更复杂。这就像连接每个高级索引元素的索引结果一样

在最简单的情况下,只有一个单一的指标先进。单个高级索引可以例如替换切片,并且结果数组将是相同的,但是,它是副本并且可以具有不同的存储器布局。当可能时,切片是优选的。

>>>
>>> x[1:2, 1:3]
array([[4, 5]])
>>> x[1:2, [1, 2]]
array([[4, 5]])

了解情况的最简单方法可能是考虑结果形状。索引操作分为两部分,即由基本索引(不包括整数)定义的子空间和来自高级索引部分的子空间。需要区分两种索引组合:

高级索引由切片分隔,Ellipsis或newaxis。例如。x[arr1, :, arr2]

高级索引彼此相邻。例如但不是 因为在这方面是一个高级索引。x[..., arr1, arr2, :] x[arr1, :, 1]1

在第一种情况下,高级索引操作产生的维度首先出现在结果数组中,然后是子空间维度。在第二种情况下,高级索引操作的维度将插入到结果数组中与初始数组中相同的位置(后一种逻辑使简单的高级索引行为就像切片一样)。


假设x.shape为(10,20,30)并且ind是(2,3,4)形索引intp数组,则其形状为(10,2,3,4,30),因为(20,)形子空间已被替换具有(2,3,4)形的广播索引子空间。如果我们让i,j,k循环遍及(2,3,4)形子空间 。此示例产生的结果与。result = x[...,ind,:]result[...,i,j,k,:] = x[...,ind[i,j,k],:]x.take(ind, axis=-2)


设x.shape(10,20,30,40,50)并假设ind_1 并ind_2可以广播到形状(2,3,4)。然后 x[:,ind_1,ind_2]具有形状(10,2,3,4,40,50),因为来自X的(20,30)形子空间已经被索引的(2,3,4)子空间替换。但是,它 x[:,ind_1,:,ind_2]具有形状(2,3,4,10,30,50),因为在索引子空间中没有明确的位置,所以它在开头就被添加了。始终可以使用 .transpose()在任何需要的位置移动子空间。请注意,此示例无法使用复制take。

布尔数组索引

当obj是布尔类型的数组对象时,会发生此高级索引,例如可能从比较运算符返回。x[obj.nonzero()]如上所述,单个布尔索引数组实际上与obj.nonzero()返回obj.ndim显示objTrue元素的整数索引数组的元组(长度)相同。但是,它更快。obj.shape == x.shape

如果,返回一个1维数组,该数组填充了与obj 值对应的x元素。搜索顺序为行主,C风格。如果物镜具有在该外侧是的边界的条目值X,则索引错误将被提高。如果obj小于x,则与填充它相同。obj.ndim == x.ndimx[obj]TrueTrueFalse


一个常见的用例是过滤所需的元素值。例如,可能希望从阵列中选择非NaN的所有条目:

>>>
>>> x = np.array([[1., 2.], [np.nan, 3.], [np.nan, np.nan]])
>>> x[~np.isnan(x)]
array([ 1., 2., 3.])

或者希望为所有负面元素添加常量:

>>>
>>> x = np.array([1., -1., -2., 3])
>>> x[x < 0] += 20
>>> x
array([ 1., 19., 18.,  3.])

通常,如果索引包括布尔数组,则结果将与插入obj.nonzero()相同位置并使用上述整数数组索引机制相同。 相当于 。x[ind_1, boolean_array, ind_2]x[(ind_1,) + boolean_array.nonzero() + (ind_2,)]

如果只有一个布尔数组且没有整数索引数组,则这是直截了当的。必须注意确保布尔索引具有与其应该使用的维度完全相同的维度。


从数组中,选择总和小于或等于2的所有行:

>>>
>>> x = np.array([[0, 1], [1, 1], [2, 2]])
>>> rowsum = x.sum(-1)
>>> x[rowsum <= 2, :]
array([[0, 1],
    [1, 1]])

但如果rowsum还有两个维度:

>>>
>>> rowsum = x.sum(-1, keepdims=True)
>>> rowsum.shape
(3, 1)
>>> x[rowsum <= 2, :]  # fails
IndexError: too many indices
>>> x[rowsum <= 2]
array([0, 1])

由于额外的维度,最后一个只给出了第一个元素。比较rowsum.nonzero()以了解此示例。

通过obj.nonzero()类比可以最好地理解组合多个布尔索引数组或布尔与整数索引数组 。该函数ix_ 还支持布尔数组,并且可以毫无意外地工作。


使用布尔索引选择加起来为偶数的所有行。同时,应使用高级整数索引选择列0和2。使用该ix_功能可以通过以下方式完成:

>>>
>>> x = array([[ 0, 1, 2],
...      [ 3, 4, 5],
...      [ 6, 7, 8],
...      [ 9, 10, 11]])
>>> rows = (x.sum(-1) % 2) == 0
>>> rows
array([False, True, False, True])
>>> columns = [0, 2]
>>> x[np.ix_(rows, columns)]
array([[ 3, 5],
    [ 9, 11]])

没有np.ix_呼叫或只选择对角线元素。

或者没有np.ix_(比较整数数组示例):

>>>
>>> rows = rows.nonzero()[0]
>>> x[rows[:, np.newaxis], columns]
array([[ 3, 5],
    [ 9, 11]])

详细说明

这些是一些详细的注释,对于日常索引(无特定顺序)并不重要:

本机NumPy索引类型intp可能与默认的整数数组类型不同。intp是足以安全索引任何数组的最小数据类型; 对于高级索引,它可能比其他类型更快。

对于高级分配,通常不保证迭代顺序。这意味着如果元素设置不止一次,则无法预测最终结果。

空(元组)索引是零维数组的完整标量索引。 如果是零维则x[()]返回标量,否则返回x视图。另一方面,x[...]总是返回一个视图。

如果索引中存在零维数组并且它是完整的整数索引,则结果将是标量而不是零维数组。(不会触发高级索引。)
当存在省略号(...)但没有大小(即替换为零 :)时,结果仍将始终为数组。如果没有高级索引,则为视图,否则为副本。

nonzero布尔数组的等价性不适用于零维布尔数组。

当高级索引操作的结果没有元素但单个索引超出范围时,是否IndexError引发了未定义(例如,超出范围)。x[[], [123]]123

当在赋值期间发生转换错误时(例如,使用字符串序列更新数值数组),被分配的数组可能最终处于不可预测的部分更新状态。但是,如果发生任何其他错误(例如超出范围索引),则阵列将保持不变。

高级索引结果的内存布局针对每个索引操作进行了优化,并且不能假设特定的内存顺序。

当使用一个子类(尤其是其操纵它的形状),默认ndarray.__setitem__行为会调用__getitem__的 基本索引而不是先进的索引。对于这样的子类,最好ndarray.__setitem__使用基类 ndarray视图调用数据。如果子类不返回视图,则必须执行此操作__getitem__。

现场访问

也可以看看

数据类型对象(dtype),标量

如果ndarray对象是结构化数组 ,则可以通过使用字符串索引数组来访问数组的字段,类似于字典。

索引x['field-name']返回数组的新视图,该视图与x具有相同的形状(当字段是子数组时除外)但是数据类型x.dtype['field-name']并且仅包含指定字段中的部分数据。还 记录阵列标量可以被“索引”这种方式。

索引到结构化数组也可以使用字段名称列表来完成, 例如 x[['field-name1','field-name2']]。从NumPy 1.16开始,这将返回仅包含这些字段的视图。在旧版本的numpy中它返回了一个副本。有关多字段索引的详细信息,请参阅结构化阵列的用户指南部分。

如果访问的字段是子数组,则子数组的尺寸将附加到结果的形状。

>>>
>>> x = np.zeros((2,2), dtype=[('a', np.int32), ('b', np.float64, (3,3))])
>>> x['a'].shape
(2, 2)
>>> x['a'].dtype
dtype('int32')
>>> x['b'].shape
(2, 2, 3, 3)
>>> x['b'].dtype
dtype('float64')

Flat Iterator索引

x.flat返回一个迭代器,它将遍历整个数组(以C-contiguous样式,最后一个索引变化最快)。只要选择对象不是元组,也可以使用基本切片或高级索引对此迭代器对象建立索引。这应该从x.flat一维视图的事实中清楚。它可以用于具有1维C风格平面索引的整数索引。因此,任何返回数组的形状都是整数索引对象的形状。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
用Python的Tornado框架结合memcached页面改善博客性能
Apr 24 Python
python中 chr unichr ord函数的实例详解
Aug 06 Python
python中abs&amp;map&amp;reduce简介
Feb 20 Python
Python中的pack和unpack的使用
Mar 12 Python
python画图--输出指定像素点的颜色值方法
Jul 03 Python
python+selenium 点击单选框-radio的实现方法
Sep 03 Python
Python实现图像去噪方式(中值去噪和均值去噪)
Dec 18 Python
Django 自定义权限管理系统详解(通过中间件认证)
Mar 11 Python
Python基于pandas绘制散点图矩阵代码实例
Jun 04 Python
解决Python 写文件报错TypeError的问题
Oct 23 Python
python推导式的使用方法实例
Feb 28 Python
Python基础之教你怎么在M1系统上使用pandas
May 08 Python
Python使用dict.fromkeys()快速生成一个字典示例
Apr 24 #Python
python3中property使用方法详解
Apr 23 #Python
详解爬虫被封的问题
Apr 23 #Python
Python3.5 Pandas模块缺失值处理和层次索引实例详解
Apr 23 #Python
Python3.5 Pandas模块之DataFrame用法实例分析
Apr 23 #Python
Python3.5 Pandas模块之Series用法实例分析
Apr 23 #Python
使用Python控制摄像头拍照并发邮件
Apr 23 #Python
You might like
php数组函数序列之next() - 移动数组内部指针到下一个元素的位置,并返回该元素值
2011/10/31 PHP
PHP基于简单递归函数求一个数阶乘的方法示例
2017/04/26 PHP
php 提交表单 关闭layer弹窗iframe的实例讲解
2018/08/20 PHP
VBS通过WMI监视注册表变动的代码
2011/10/27 Javascript
javascript学习笔记(十二) RegExp类型介绍
2012/06/20 Javascript
js Date概念详细介绍
2013/11/22 Javascript
javascript中对Attr(dom中属性)的操作示例讲解
2013/12/02 Javascript
使用js实现的简单拖拽效果
2015/03/18 Javascript
SublimeText自带格式化代码功能之reindent
2015/12/27 Javascript
Bootstrap每天必学之响应式导航、轮播图
2016/04/25 Javascript
纯js实现手风琴效果代码
2020/04/17 Javascript
bootstrap选项卡使用方法解析
2017/01/11 Javascript
lhgcalendar时间插件限制只能选择三个月的实现方法
2017/07/03 Javascript
详解如何在Vue里建立长按指令
2018/08/20 Javascript
node.js的http.createServer过程深入解析
2019/06/06 Javascript
Vue中img的src是动态渲染时不显示的解决
2019/11/14 Javascript
[42:25]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第三场
2018/04/06 DOTA
解决Python plt.savefig 保存图片时一片空白的问题
2019/01/10 Python
Django使用list对单个或者多个字段求values值实例
2020/03/31 Python
Python正则表达式如何匹配中文
2020/05/27 Python
详解Pandas 处理缺失值指令大全
2020/07/30 Python
使用css3和jquery实现可伸缩搜索框
2014/02/12 HTML / CSS
详解HTML5通讯录获取指定多个人的信息
2016/12/20 HTML / CSS
js实现移动端H5页面手指滑动刻度尺功能
2017/11/16 HTML / CSS
丝芙兰新加坡官网:Sephora新加坡
2018/12/04 全球购物
资深生产主管自我评价
2013/09/22 职场文书
优秀村官事迹材料
2014/01/10 职场文书
社区端午节活动方案
2014/01/28 职场文书
大学奖学金获奖感言
2014/08/15 职场文书
勿忘国耻9.18演讲稿(经典篇)
2014/09/14 职场文书
2014年人大工作总结
2014/12/10 职场文书
学校端午节活动总结
2015/02/11 职场文书
简历自荐信范文
2015/03/09 职场文书
工程技术负责人岗位职责
2015/04/13 职场文书
同意转租证明
2015/06/24 职场文书
2019中小学生安全过暑期倡议书
2019/06/24 职场文书