import numpy as np #导入 NumPy 库 np.__version__ #打印numpy版本
Out[1]:
'1.22.2'
2.3 NumPy 数组操作
NumPy数组的常用操作包括形状改变、运算和统计等,这些操作大多可以通过两种方式实现:
- 通过NumPy数组ndarray类定义的方法实现
- 通过NumPy函数对数组的操作实现
两种方式功能相同,主要区别在于通过NumPy函数操作时,函数的第一个参数是要操作的数组。而通过ndarray类的相应方法则没有该参数,因为数组本身对象来调用方法。
2.3.1 修改数组形状
改变形状-reshape方法/函数
在不改变元素数目条件下修改形状,即各维度的形状乘积要等于数组元素总数,调用方式:
-
通过NumPy数组方法调用格式如下:
- numpy.ndarray.reshape(newshape, order='C'),其中ndarray就是创建的数组对象
-
通过NumPy函数调用格式如下:
-
numpy.reshape(arr, newshape, order='C'),其中arr就是创建的数组对象
-
newshape参数:表示各维度shape参数,可以是一个整数或者整数数组,转成一维数组用一个整数传入;转成多维数组时,函数reshape的该参数只能用整数数组或元组、列表的组合方式表示,不能分开传入,而数组的方法reshape则可以分开传入,这点需要注意区分。
-
order参数:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'k' -- 元素在内存中的出现顺序。
-
In [2]:
arr3_1_1 = np.arange(12) #创建一维数组 arr3_1_1
Out[2]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
In [3]:
arr3_1_1.ndim #维度为1
Out[3]:
1
对该数组对象调用reshape方法,将一维数组改为shape形状(3,4),3 * 4=12个元素,保持元素数目不变
In [4]:
arr3_1_2 = arr3_1_1.reshape(3,4) #调用数组方法reshape,各维度参数可以分开传入,也可以组合传入:arr1.reshape((3,4)) arr3_1_2
Out[4]:
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
In [5]:
arr3_1_2.reshape(12) #传入一个整数转成一维数组
Out[5]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
或者是通过reshape函数调用:
In [6]:
arr3_1_3 = np.reshape(arr3_1_1,(3,4)) #第一个参数是需要改变形状的数组,第二个参数是shape形状,只能通过整数数组或元组列表的组合方式传入,不能分开传入 arr3_1_3
Out[6]:
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
In [7]:
arr3_1_3.ndim #维度为2,行和列两个维度
Out[7]:
2
In [8]:
arr3_1_4 = arr3_1_1.reshape(4,-1) arr3_1_4
Out[8]:
array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]])
-1表示除了确定的轴长4外剩余的轴长,即arr1元素个数为12/4=3,所以-1表示3
In [9]:
arr3_1_4.shape #形状为4行3列
Out[9]:
(4, 3)
将一维数组改为shape形状(2,4,3),2 * 4 * 3=24个元素,保持元素数目不变
In [10]:
arr3_1_5 = np.arange(24).reshape(2,4,-1) arr3_1_5
Out[10]:
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]]])
In [11]:
arr3_1_5.ndim
Out[11]:
3
In [12]:
arr3_1_5.shape
Out[12]:
(2, 4, 3)
维度为3,对应[[[ ]]]],最里面第三层的[]每个有3个元素,第二层的[]每个有4个元素,对应于四个第三层,而最外面层有2个元素,对应两个第二层
注意:后面介绍的NumPy数组操作就不再区分是调用NumPy数组对象的方法还是调用NumPy函数,只以其中一种方式进行讲解。两者总体区别在于:
- 调用方式不同,数组方法调用是:NumPy数组对象.方法名(),函数调用是:np.函数名(),
- 调用NumPy函数的第一个参数一般是NumPy数组。
展平数组-ravel()函数
展平数组元素功能,即从多维转变成一维数组。返回的是数组视图,修改展平后的数组会影响原始数组。
In [13]:
arr3_1_6 = np.arange(6).reshape(2,3) arr3_1_6
Out[13]:
array([[0, 1, 2], [3, 4, 5]])
In [14]:
arr3_1_7 = arr3_1_6.ravel() #通过ndarray数组对象的方法调用,展平数组元素,默认按行展平 arr3_1_7
Out[14]:
array([0, 1, 2, 3, 4, 5])
或者:
In [15]:
arr3_1_8 = np.ravel(arr3_1_6) #通过NumPy函数调用,展平数组元素,默认按行展平 arr3_1_8
Out[15]:
array([0, 1, 2, 3, 4, 5])
In [16]:
arr3_1_8[1] = 100 arr3_1_8
Out[16]:
array([ 0, 100, 2, 3, 4, 5])
In [17]:
arr3_1_6
Out[17]:
array([[ 0, 100, 2], [ 3, 4, 5]])
指定展开方式,如按列展平数组元素,也就是先第0列从上往下,再第1列从上往下输出:
In [18]:
arr3_1_9 = arr3_1_6.ravel('F') #按列展平数组元素 arr3_1_9
Out[18]:
array([ 0, 3, 100, 4, 2, 5])
In [19]:
arr3_1_9[1] = 100 arr3_1_9
Out[19]:
array([ 0, 100, 100, 4, 2, 5])
In [20]:
arr3_1_6
Out[20]:
array([[ 0, 100, 2], [ 3, 4, 5]])
可以看到,若按行展平(默认),展平后数组重新赋值后,原数组对应位置值也改变。若按列展平,展平后数组重新赋值后,原数组对应位置值没有改变。
多维数组的展平:
In [21]:
arr3_1_10 = np.arange(24).reshape(2,3,4) arr3_1_10
Out[21]:
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]]])
In [22]:
arr3_1