2025年4月1日 星期二 乙巳(蛇)年 正月初二 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

Numpy切片基础操作详解

时间:03-29来源:作者:点击数:102

1. 多维数组的切片操作

1) 列表切片与Numpy数组切片

在讲解多维数组的切片操作之前,我们看一看简单的一维数组切片是如何进行操作的,我们知道在 Python 的列表类型中有浅拷贝和深拷贝之说,在一个列表上进行切片操作,会生成一个新的列表。也就是说列表的切片操作不会影响到列表源数据。

  • In [1]: a=[1,2,3,4,5,6]
  • In [2]: a[::]
  • Out[4]: [1, 2, 3, 4, 5, 6]
  • In [3]: a=[1,2,3,4,5,6]
  • In [4]: id(a)
  • #原列表内存地址
  • Out[4]: 136347440
  • In [5]: id(a[::])
  • #切片后新列表的内存地址
  • Out[5]: 136153128

由上述代码可见内存地址发生了变化。下面我们看看 Numpy 数组的切片是怎样的,如下:

  • In [1]: import numpy as np
  • In [2]: data=np.array([1,2,3,4])
  • #切片操作
  • In [3]: data[0:4]
  • Out[3]: array([1, 2, 3, 4])
  • In [4]: id(data)
  • Out[4]: 84768232
  • #切片赋值操作
  • In [5]: data[0:4]=1
  • In [6]: data
  • Out[6]: array([1, 1, 1, 1])
  • #内存地址相同
  • In [7]: id(data)
  • Out[7]: 84768232

由此可见,当你传递一个数值给数组的切片的时候,数据被传递给了整个切片,这代表数据并不是被复制了,而是说明数组切片是在源数组上进行的。我们继续上面的演示:

  • #截取data1生成新的数组
  • In [12]: data1=data[1:3]
  • In [13]: data1
  • Out[13]: array([1, 1])
  • #分别利用索引给data和data1的0位置进行赋值
  • In [14]: data[0]=12134
  • In [15]: data1[0]=12134
  • #在调用data原数组
  • In [16]: data
  • Out[16]: array([12134, 12134, 1, 1])

可以看到非常神奇的事情发生了,当我们改变 data1时候,最终的变化也会体现在原数组上,初次接触到 Numpy 的小伙伴也许会感到惊讶,那么为什么会是这个样子的呢?

其实 Numpy 设计之初是针对非常大的数组来开发的,这就带来一个问题,如果 Numpy 每一次切片操作都要复制数据,这将会引起多少的内存占用。所以 Numpy 采用这种设计方式比较适合自身的特性。如果你就是想要一份数组切片的拷贝的话,这里需要使用 copy() 方法,将会得到一个副本,而上述过程中对原数组切片操作后得到的数组称为视图,比如原数组是a,切片后得到 b 数组,那么 b 叫做 a 的视图,这在下一篇文章我们还会讲解。

data[1:3].copy() #得到数组的副本

如果操作副本的话,将不会影响到源数组数据。

2) 二维数组切片基本操作

下面我们看二维数组的切片操作,示例如下:

  • In [1]: import numpy as np
  • In [2]: a=np.array([[1,2,3],[4,5,6]])
  • In [3]: a
  • Out[3]:
  • array([[1, 2, 3],
  • [4, 5, 6]])
  • In [4]: a[:]
  • Out[4]:
  • array([[1, 2, 3],
  • [4, 5, 6]])
  • In [5]: a[0:1]
  • Out[5]: array([[1, 2, 3]])
  • In [6]: a[1:2]
  • Out[6]: array([[4, 5, 6]])
  • In [7]: a[:2]
  • Out[7]:
  • array([[1, 2, 3],
  • [4, 5, 6]])

数组的切片操作,如 a[:2] 表示前两行,即 a 数组的全部,此时把 a 看做一个整体来进行操作,同时我们还可以进行多数组切片,这与多数组索引的使用方法类似,如下所示:

  • In [1]: import numpy as np
  • In [2]: a=np.array([[1,2,3],[4,5,6]])
  • In [3]: a
  • Out[3]:
  • array([[1, 2, 3],
  • [4, 5, 6]])
  • In [4]: a[:,1]
  • Out[4]: array([2, 5])
  • In [5]: a[1,:]
  • Out[5]: array([4, 5, 6])
  • In [6]: a[:,:]
  • Out[6]:
  • array([[1, 2, 3],
  • [4, 5, 6]])
  • In [7]: a[0,:]
  • Out[7]: array([1, 2, 3])
  • In [8]: a[1:,:]
  • Out[8]: array([[4, 5, 6]])

对于二维数组来说,我们要按照行列的思想去理解它,形如 a[n,:]、a[:,n]、a[m:n,:]、a[:,m:n],都属于二维数组的切片形式,中括号中的第一个位置代表截取行,第二个位置代表截取列,中间需用逗号隔开。注意,我们要将 m:n 看做是一个整体,使用切片操作二维数组的中括号中就有一个冒号,三维数组就会有两个冒号,以此类推,且每个冒号与之间用逗号隔开,如 a[1:,:] 它的含义可以这样理解:

  • 行位置表示截取第一行开始到末行终止;
  • 列位置表示截取所有的列;

3) 三维数组切片的理解

按照上面二维数组的操作方式,理解三维数组的切片操作会简单一些,还是按照三维数组中 [个数:行:列] 的思想去理解它。三维的切片形如 b[n,::]、b[:,n:]、b[::,n]、b[:,:,n]、b[m:n,::]、b[:,m:n:]、b[::,m:n]、b[:,:,m:n],下面看一些简单的示例操作,方便大家进行理解:

  • In [15]: b=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
  • #生成三维数组,由两个二维数组组成
  • In [16]: b
  • Out[16]:
  • array([[[ 1, 2, 3],
  • [ 4, 5, 6]],
  • [[ 7, 8, 9],
  • [10, 11, 12]]])
  • In [16]: b[1,1,:]
  • Out[16]: array([10, 11, 12])
  • #最后生成的是两行两列的数组
  • In [17]: b[:,:,1]
  • Out[17]:
  • array([[ 2,5],
  •        [ 8,11]])

只要记住中括号中的三个位置分别代着不同的操作,这样理解起来就变得非常简单了。本节知识的需要各位小伙伴以注重理解为先,根据示例大家要多多的动手操作,用心去体会它的使用方法。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门