12.NumPy相关数组操作
NumPy 中包含了一些处理数组的常用方法,大致可分为以下几类:
- 数组变维操作
- 数组转置操作
- 修改数组维度操作
- 连接与分割数组操作
下面分别对它们进行介绍。
数组变维操作
函数名称 | 函数介绍 |
---|---|
reshape | 在不改变数组元素的条件下,修改数组的形状。 |
flat | 返回是一个迭代器,可以用 for 循环遍历其中的每一个元素。 |
flatten | 以一维数组的形式返回一份数组的副本,对副本的操作不会影响到原数组。 |
ravel | 返回一个连续的扁平数组(即展开的一维数组),与 flatten不同,它返回的是数组视图(修改视图会影响原数组)。 |
reshape 在《NumPy ndarray对象》一节已经做了讲解,本节不再介绍。
1) numpy.ndarray.flat
numpy.ndarray.flat 返回一个数组迭代器,实例如下:
- import numpy as np
- a = np.arange(9).reshape(3,3)
- for row in a:
- print (row)
- #使用flat属性:
- for ele in a.flat:
- print (ele,end=",")
输出结果如下:
#原数组
[0 1 2]
[3 4 5]
[6 7 8]
#输出元素
0,1,2,3,4,5,6,7,8,
2) numpy.ndarray.flatten()
numpy.ndarray.flatten 返回一份数组副本,对副本修改不会影响原始数组,其语法格式如下:
ndarray.flatten(order='C')
实例如下:
- import numpy as np
- a = np.arange(8).reshape(2,4)
- print (a)
- #默认按行C风格展开的数组
- print (a.flatten())
- #以F风格顺序展开的数组
- print (a.flatten(order = 'F'))
输出结果:
#数组a
[[0 1 2 3]
[4 5 6 7]]
#默认c顺序站看数组
[0 1 2 3 4 5 6 7]
# F顺序站看数组
[0 4 1 5 2 6 3 7]
3) numpy.ravel()
numpy.ravel() 将多维数组中的元素以一维数组的形式展开,该方法返回数组的视图(view),如果修改,则会影响原始数组。
numpy.ravel(a, order='C')
实例结果如下:
- import numpy as np
- a = np.arange(8).reshape(2,4)
- print ('原数组:')
- print (a)
- print ('调用 ravel 函数后:')
- print (a.ravel())
- print ('F 风格顺序调用 ravel 函数之后:')
- print (a.ravel(order = 'F'))
输出结果如下:
原数组:
[[0 1 2 3]
[4 5 6 7]]
调用 ravel 函数后:
[0 1 2 3 4 5 6 7]
F 风格顺序调用 ravel 函数之后:
[0 4 1 5 2 6 3 7]
数组转置操作
函数名称 | 说明 |
---|---|
transpose | 将数组的维度值进行对换,比如二维数组维度(2,4)使用该方法后为(4,2)。 |
ndarray.T | 与 transpose 方法相同。 |
rollaxis | 沿着指定的轴向后滚动至规定的位置。 |
swapaxes | 对数组的轴进行对换。 |
1) numpy.transpose()
numpy.transpose() 用于对换多维数组的维度,比如二维数组使用此方法可以实现矩阵转置,语法格式如下:
numpy.transpose(arr, axes)
参数说明如下:
- arr:要操作的数组
- axes:可选参数,元组或者整数列表,将会按照该参数进行转置。
示例如下:
- import numpy as np
- a = np.arange(12).reshape(3,4)
- print (a)
- print (np.transpose(a))
输出结果:
原数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
对换数组:
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
ndarray.T 的使用方法与其类似,这里就在赘述。
2) numpy.rollaxis()
该方法表示沿着指定的轴,向后滚动至一个特定位置,格式如下:
numpy.rollaxis(arr, axis, start)
参数说明:
- arr:要传入的数组;
- axis:沿着哪条轴向后滚动,其它轴的相对位置不会改变;
- start:默认以 0 轴开始,可以根据数组维度调整它的值。
3) numpy.swapaxes()
该方法用于交换数组的两个轴,其语法格式如下:
numpy.swapaxes(arr, axis1, axis2)
示例如:
- import numpy as np
- # 创建了三维的 ndarray
- a = np.arange(27).reshape(3,3,3)
- print (a)
- #对换0轴与2轴
- print(np.swapaxes(a,2,0))
输出结果:
#原a数组
[[[ 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]]]
#对换轴后的数组
[[[ 0 9 18]
[ 3 12 21]
[ 6 15 24]]
[[ 1 10 19]
[ 4 13 22]
[ 7 16 25]]
[[ 2 11 20]
[ 5 14 23]
[ 8 17 26]]]
修改数组维度操作
修改数组维度的操作,主要有以下方法:
函数名称 | 描述说明 |
---|---|
broadcast | 生成一个模拟广播的对象。 |
broadcast_to | 将数组广播为新的形状。 |
expand_dims | 扩展数组的形状。 |
squeeze | 从数组的形状中删除一维项。 |
1) numpy.broadcast()
返回值是数组被广播后的对象,该函数以两个数组作为输入参数,实例如下:
- import numpy as np
- a = np.array([[1], [2], [3]])
- b = np.array([4, 5, 6])
- # 对b广播a
- d = np.broadcast(a,b)
- #d它拥有 iterator 属性
- r,c = d.iters
- print (next(r), next(c))
- print (next(r), next(c))
- # 使用broadcast将a与b相加
- e = np.broadcast(a,b)
- f=np.empty(e.shape)
- f.flat=[x+y for (x,y) in e]
- print(f)
- print(a+b)
输出结果:
#对b广播a
1 6
2 4
#f数组
[[5. 6. 7.]
[6. 7. 8.]
[7. 8. 9.]]
#a+b
[[5 6 7]
[6 7 8]
[7 8 9]]
2) numpy.broadcast_to()
该函数将数组广播到新形状中,它在原始数组的基础上返回一个只读视图。 如果新形状不符合 NumPy 的广播规则,则会抛出 ValueError 异常。函数的语法格式如下:
numpy.broadcast_to(array, shape, subok)
使用实例如下所示:
- import numpy as np
- a = np.arange(4).reshape(1,4)
- print("原数组",a)
- print ('调用 broadcast_to 函数之后:')
- print (np.broadcast_to(a,(4,4)))
最后的输出结果如下:
#原数组
[[0 1 2 3]]
#调用 broadcast_to 函数之后:
[[0 1 2 3]
[0 1 2 3]
[0 1 2 3]
[0 1 2 3]]
3) numpy.expand_dims()
在指定位置插入新的轴,从而扩展数组的维度,语法格式如下:
numpy.expand_dims(arr, axis)
参数说明:
- arr:输入数组
- axis:新轴插入的位置
实例如下:
- import numpy as np
- x = np.array(([1,2],[3,4]))
- print ('数组 x:')
- print (x)
- # 在 0 轴处插入新的轴
- y = np.expand_dims(x, axis = 0)
- print ('数组 y:')
- print (y)
- print ('\n')
- print ('数组 x 和 y 的形状:')
- print (x.shape, y.shape)
输出结果为:
数组 x:
[[1 2]
[3 4]]
数组 y:
[[[1 2]
[3 4]]]
数组 x 和 y 的形状:
(2, 2) (1, 2, 2)
4) numpy.squeeze()
删除数组中维度为 1 的项,例如,一个数组的 shape 是 (5,1),经此函数后,shape 变为 (5,) 。其函数语法格式如下:
numpy.squeeze(arr, axis)
参数说明:
- arr:输入数的组;
- axis:取值为整数或整数元组,用于指定需要删除的维度所在轴,指定的维度值必须为 1 ,否则将会报错,若为 None,则删除数组维度中所有为 1 的项。
下面是带有 axis 参数的实例:
- >>> x = np.array([[[0], [1], [2]]])
- >>> x.shape
- (1, 3, 1)
- >>> np.squeeze(x).shape
- (3,)
- >>> np.squeeze(x, axis=(2,)).shape
- (1, 3)
再看另一组示例,如下所示:
- import numpy as np
- a = np.arange(9).reshape(1,3,3)
- print (a)
- b = np.squeeze(a)
- print (b)
- print ('数组 a 和 b 的形状:')
- print (x.shape, y.shape)
输出结果为:
数组 a:
[[[0 1 2]
[3 4 5]
[6 7 8]]]
数组 b:
[[0 1 2]
[3 4 5]
[6 7 8]]
数组 a 和 b 的形状:
(1, 3, 3) (3, 3)
连接与分割数组操作
连接与分割数组是数组的两种操作方式,我们为了便于大家记忆,现将它们的方法整合在一起,如下所示:
类型 | 函数名称 | 描述说明 |
---|---|---|
连接数组方法 | concatenate | 沿指定轴连接两个或者多个相同形状的数组 |
stack | 沿着新的轴连接一系列数组 | |
hstack | 按水平顺序堆叠序列中数组(列方向) | |
vstack | 按垂直方向堆叠序列中数组(行方向) | |
分割数组方法 | split | 将一个数组分割为多个子数组 |
hsplit | 将一个数组水平分割为多个子数组(按列) | |
vsplit | 将一个数组垂直分割为多个子数组(按行) |
1) 连接数组操作
numpy.concatenate() 沿指定轴连接相同形状的两个或多个数组,格式如下:
numpy.concatenate((a1, a2, ...), axis)
参数说明:
- a1, a2, ...:表示一系列相同类型的数组;
- axis:沿着该参数指定的轴连接数组,默认为 0。
实例说明:创建两个 a 、b 数组,并沿指定轴将它们连接起来。注意两个数组的形状要保持一致。
- import numpy as np
- #创建数组a
- a = np.array([[10,20],[30,40]])
- print (a)
- #创建数组b
- b = np.array([[50,60],[70,80]])
- print (b)
- #沿轴 0 连接两个数组
- print (np.concatenate((a,b)))
- #沿轴 1 连接两个数组
- print (np.concatenate((a,b),axis = 1))
输出结果:
#a
[[10 20]
[30 40]]
#b
[[50 60]
[70 80]]
#axis=0沿着垂直方向
[[10 20]
[30 40]
[50 60]
[70 80]]
#axis=1沿着水平方向
[[10 20 50 60]
[30 40 70 80]]
数组连接操作至少需要两个维度相同的数组,才允许对它们进行垂直或者水平方向上的操作。
在垂直方向堆叠数组,示例如下:
- import numpy as np
- a = np.array([[1,2],[3,4]])
- b = np.array([[5,6],[7,8]])
- #垂直堆叠
- c = np.vstack((a,b))
- print (c)
输出结果如下:
[[1 2]
[3 4]
[5 6]
[7 8]]
2) 分割数组操作
numpy.split() 沿指定的轴将数组分割为多个子数组,语法格式如下:
numpy.split(ary, indices_or_sections, axis)
参数说明:
- ary:被分割的数组
- indices_or_sections:若是一个整数,代表用该整数平均切分,若是一个数组,则代表沿轴切分的位置(左开右闭);
- axis:默认为0,表示横向切分;为1时表示纵向切分。
示例如下所示:
- import numpy as np
- a = np.arange(6)
- #原数组
- print (a)
- #将数组分为二个形状大小相等的子数组
- b = np.split(a,2)
- print (b)
- #将数组在一维数组中标明要位置分割
- b = np.split(a,[3,4])
- print (b)
输出结果如下:
#a数组
[0 1 2 3 4 5]
#切分分形状大小相同的数组
[array([0, 1, 2]), array([3, 4, 5])]
#按数组标明位置切分,切分时左开右闭
[array([0, 1, 2]), array([3]), array([4, 5])]
最后看一下 hsplit() 的使用方法,示例如下:
- import numpy as np
- #arr1数组
- arr1 = np.floor(10 * np.random.random((2, 6)))
- print(arr1)
- #拆分后数组
- print(np.hsplit(arr1, 3))
输出结果:
#原arr1数组
[[2. 1. 5. 3. 1. 7.]
[1. 2. 9. 0. 9. 9.]]
#经过水平切分后得到的数组
[array([[2., 1.],
[1., 2.]]), array([[5., 3.],
[9., 0.]]), array([[1., 7.],
[9., 9.]])]]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)