python之numpy
numpy是一个多维的数组对象,类似python的列表,但是数组对象的每个元素之间由空格隔开。
一、数组的创建
1.通过numpy的array(参数),参数可以是列表、元组、数组、生成器等
由arr2和arr3看出,对于多维数组来说,如果最里层的数据类型不一致,array()会将其转化为一致
由arr2和arr4看出,对于最里层的数据个数不一致,array()的结果只是一个一维数组。
import numpy as np arr1 = np.array(range(10)) arr2 = np.array([[1,2,3],[4,5,6]]) arr3 = np.array([[1,2,3],['a','b','c']]) arr4 = np.array([[1,2,3],['a','b']]) print(arr1) print(arr2) print(arr3) print(arr4)
2.通过numpy的arange(start,stop,step=1,dtype)创建一维数组
start表示起始值,stop表示终止值(包含start但不包含stop,即前闭后开区间),step表示步长默认为1,dtype表示元素类型,其中stop和step可省略。
arr5 = np.arange(5) #[0 1 2 3 4] arr6 = np.arange(1.0,6) #[1. 2. 3. 4. 5. ] arr7 = np.arange(1.0,6,dtype = int) #[1 2 3 4 5] arr8 = np.arange(1,8,2) #[1 3 5 7]
3.通过reshape(m,n)创建
如下示例表示创建10个0-1之间的随机数,然后生成一个二维数组,每个数组5个元素。
arr = np.random.rand(10).reshape(2,5) print(arr) # [[0.03377643 0.17232537 0.55157918 0.96107258 0.50468264] # [0.85299258 0.50271173 0.31466024 0.89302 0.82547851]]
4.通过linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)创建一维数组
start:起始值
stop:终止值,默认包含stop
num:数组元素的个数,默认为50个
endpoint:数组是否包含stop,默认为true包含,false表示不包含
retstep:数组是否显示步长,默认为false不显示,只显示数组;true表示结果显示为一个元组,元组的第一个元素为数组第二个元素为步长
dtype:数组元素的类型
arr1 = np.linspace(1,5,num=5) #[1. 2. 3. 4. 5.] arr2 = np.linspace(1,6,num=5,endpoint=False,retstep=True,dtype=int) #(array([1, 2, 3, 4, 5]), 1.0)
5.通过zeros(shape,dtype=float)和zeros_like(arr,dtype)创建元素全部为0的多维数组
zeros()表示创建一个数组,纬度为参数shape,元素全部为0且默认类型为float
zeros_like()表示创建一个类似参数arr结构的数组,元素全部为0,元素类型默认与arr保持一致,也可自定义元素类型。
arr1 = np.zeros(3) arr2 = np.zeros([3,2],dtype = int) arr3 = np.zeros_like(arr1,dtype = int) print(arr1) print(arr2) print(arr3) # [0. 0. 0.] # [[0 0] # [0 0] # [0 0]] # [0 0 0]
6.通过ones(shape,dtype=float)和ones_like(arr,dtype)创建元素全部为1的多维数组
ones()和ones_like()的用法类似zeros()和zeros_like()的用法,只是数组的元素的值为1。
arr1 = np.ones(2) arr2 = np.ones((2,3),dtype = int) arr3 = np.ones_like(arr1,dtype = int) print(arr1) print(arr2) print(arr3) # [1. 1.] # [[1 1 1] # [1 1 1]] # [1 1]
7.通过eye(n,dtype = float)创建多维数组
eye()表示创建n*n的数组,对角线元素为1其他元素为0,默认元素类型为float。
arr1 = np.eye(2) arr2 = np.eye(3,dtype = int) print(arr1) print(arr2) # [[1. 0.] # [0. 1.]] # [[1 0 0] # [0 1 0] # [0 0 1]]
二、数组常用属性
- type(arr) 数组类型
- arr.ndim 数组的秩,即轴的数量或纬度的数量
- arr.shape 数组的形状,形式为(m,n),对于二位数组来说m表示行n表示列
- arr.size 数组元素的总个数,相当于shape中的m*n
- arr.dtype 数组元素的类型
- arr.itemsize 数组元素的大小,单位为字节
- arr.data 实际数组元素的缓冲区
arr = np.array(([1,2,3],[4,5,6])) print(type(arr)) #<class 'numpy.ndarray'> print(arr.ndim) #2 print(arr.shape) #(2, 3) print(arr.size) #6 print(arr.dtype) #int32 print(arr.itemsize)# 4 print(arr.data) #<memory at 0x000002DADBB082D0>
三、数组的索引
①数值索引
数组的数值索引类似python列表和元组的索引,从0开始,且切片[m:n]表示包括m但不包括n。
对于嵌套列表和元组来说,可通过l[m][n]获取第二层的值,在numpy中除了这种方法,还可通过arr[m,n]来获取,m表示行n表示列。
arr = np.arange(12).reshape(2,2,3) print(arr) print(arr[0][1][1:]) print(arr[1][0][2]) print(arr[1,0,2]) # [[[ 0 1 2] # [ 3 4 5]] # # [[ 6 7 8] # [ 9 10 11]]] # [4 5] # 8 # 8
②布尔索引
使用布尔索引时,False表示不保留,True表示保留,如下例子h表示在水平方向的索引规则,即保留第二行,v表示在竖直方向的索引规则,保留第一列和第三列。
arr = np.arange(12).reshape(3,4) h = np.array([False,True,False]) v = np.array([True,False,True,False]) print(arr) print(arr[h]) print(arr[:,v]) print(arr[h,v]) # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # [[4 5 6 7]] # [[ 0 2] # [ 4 6] # [ 8 10]] # [4 6]
arr = np.arange(12).reshape(2,6) m = (arr>8) n = (arr<3) print(m) print(n) print(arr[m]) print(arr[n]) # [[False False False False False False] # [False False False True True True]] # [[ True True True False False False] # [False False False False False False]] # [ 9 10 11] # [0 1 2]
四、数组常用方法
1..T转置
.T会对原数组进行转置操作,一维数组转置后的结果与原数组相同。
.T会生成新的数组,修改原数组会影响转置后的数组,修改转置后的数组也会影响原数组,即两者指向相同的内存地址。
arr1 = np.arange(5) print(arr1) arr2 = arr1.T print(arr2) arr1[1]=10 arr2[3]=30 print(arr1,arr2) arr3 = np.array([[1,2,3],[4,5,6]]) print(arr3) arr4 = arr3.T print(arr3) print(arr4) arr3[0][0]=10 print(arr3) print(arr4) arr4[1][0]=20 print(arr3) print(arr4) # [0 1 2 3 4] # [0 1 2 3 4] # [ 0 10 2 30 4] [ 0 10 2 30 4] # [[1 2 3] # [4 5 6]] # [[1 2 3] # [4 5 6]] # [[1 4] # [2 5] # [3 6]] # [[10 2 3] # [ 4 5 6]] # [[10 4] # [ 2 5] # [ 3 6]] # [[10 20 3] # [ 4 5 6]] # [[10 4] # [20 5] # [ 3 6]]
2.reshape()重置维度
两种用法:np.reshape(arr,shape)和arr.reshape(m,n),reshape()要求重置后的元素个数与原数组相同,否则会报错。
reshape()两种方法都会生成新的数组,修改原数组会影响重置维度后的数组,修改重置维度后的数组也会影响原数组,即两者指向相同的内存地址。
arr1 = np.ones((3,2),dtype = int) print(arr1) arr2 = np.reshape(arr1,[2,3]) #xin print(arr2) arr3 = arr1.reshape(2,3) #yuan print(arr1) print(arr2) print(arr3) arr1[0][0] = 10 arr2[0][1] = 20 arr3[0][2] = 30 print(arr1) print(arr2) print(arr3) # [[1 1] # [1 1] # [1 1]] # [[1 1 1] # [1 1 1]] # [[1 1] # [1 1] # [1 1]] # [[1 1 1] # [1 1 1]] # [[1 1 1] # [1 1 1]] # [[10 20] # [30 1] # [ 1 1]] # [[10 20 30] # [ 1 1 1]] # [[10 20 30] # [ 1 1 1]]
3.resize()重置大小
两种用法:np.resize(arr,shape)和arr.resize(m,n),但是resize()的效果与转置和重置维度不同。
np.resize(arr,shape)会生成新的数组,修改原数组不会影响重置大小后的数组,修改重置大小后的数组也不会影响原数组,即两者是独立的。
arr.resize(m,n)直接重置arr自身的大小,不会生成新的数组。
arr1 = np.ones((3,2),dtype = int) print(arr1) arr2 = np.resize(arr1,[2,3]) print(arr2) arr3 = arr1.resize(2,3) print(arr1) print(arr2) print(arr3) arr1[0][0] = 0 arr2[1][0] = 0 print(arr1) print(arr2) print(arr3) # [[1 1] # [1 1] # [1 1]] # [[1 1 1] # [1 1 1]] # [[1 1 1] # [1 1 1]] # [[1 1 1] # [1 1 1]] # None # [[0 1 1] # [1 1 1]] # [[1 1 1] # [0 1 1]] # None
resize()不要求重置后的元素个数与原数组相同
如果重置大小后的数组元素个数比原数组少,会从原数组前开始部分取值,舍去多余的元素;
如果重置大小后的数组元素个数比原数组多,多的元素会再依次从原数组开始部分取值,直到元素个数满足要求。
arr4 = np.arange(5) arr5 = np.resize(arr4,(2,2)) arr6 = np.resize(arr4,(2,4)) print(arr4) print(arr5) print(arr6) # [0 1 2 3 4] # [[0 1] # [2 3]] # [[0 1 2 3] # [4 0 1 2]]
4.copy()复制
使用=给数组赋值,两者指向相同的内存地址,修改任一个会影响另一个。
使用copy()给数组赋值,两者是独立的数组,修改任一个不会影响另一个。
arr1 = np.arange(5) arr2 = arr1 arr3 = arr1.copy() print(arr1,arr2,arr3) arr1[1] = 10 arr2[2] = 20 arr3[3] = 30 print(arr1,arr2,arr3) # [0 1 2 3 4] [0 1 2 3 4] [0 1 2 3 4] # [ 0 10 20 3 4] [ 0 10 20 3 4] [ 0 1 2 30 4]
5.astype()数据类型转换
arr1 = np.arange(5) arr2 = arr1.astype(np.float) print(arr1,arr1.dtype) print(arr2,arr2.dtype) # [0 1 2 3 4] int32 # [0. 1. 2. 3. 4.] float64
6.hstack()和vstack()数组堆叠
hstack((arr1,arr2)):横向堆叠,即在水平方向上拼接
vstack((arr1,arr2)):竖向堆叠,即在垂直方向上拼接,垂直拼接要求两个数组横向元素的个数相同,即shape(m,n)中的n相同
arr1 = np.arange(1,6) arr2 = np.arange(6,11) print(arr1,arr2) print(np.hstack((arr1,arr2))) print(np.vstack((arr1,arr2))) print(np.stack((arr1,arr2))) #默认axis = 0 print(np.stack((arr1,arr2),axis=1)) # [1 2 3 4 5] [ 6 7 8 9 10] # [ 1 2 3 4 5 6 7 8 9 10] # [[ 1 2 3 4 5] # [ 6 7 8 9 10]] # [[ 1 2 3 4 5] # [ 6 7 8 9 10]] # [[ 1 6] # [ 2 7] # [ 3 8] # [ 4 9] # [ 5 10]]
7.hsplit()和vsplit()数组拆分
hsplit(arr , x):横向拆分为x个,即在水平方向上拆分,水平拆分要求原数组横向元素的个数为x的整数倍,即shape(m,n)中的n为x的整数倍
vsplit(arr , x):竖向拆分为x个,即在垂直方向上拆分,垂直拆分要求原数组垂直元素的个数为x的整数倍,即shape(m,n)中的m为x的整数倍
arr1 = np.arange(12).reshape(2,6) print(arr1) print(np.hsplit(arr1,3)) arr2 = np.arange(12).reshape(4,3) print(arr2) print(np.vsplit(arr2,2)) # [[ 0 1 2 3 4 5] # [ 6 7 8 9 10 11]] # [array([[0, 1], # [6, 7]]), array([[2, 3], # [8, 9]]), array([[ 4, 5], # [10, 11]])] # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11]] # [array([[0, 1, 2], # [3, 4, 5]]), array([[ 6, 7, 8], # [ 9, 10, 11]])] #
8.算数运算
①数组与单个数值进行数学运算
加、减、乘、除和幂运算都是对数组中的每一个元素进行运算。
arr = np.arange(2,12,2) print(arr) #[ 2 4 6 8 10] print(arr + 1) # 加法 [ 3 5 7 9 11] print(arr - 1) # 减法 [1 3 5 7 9] print(arr*2) # 乘法[ 4 8 12 16 20] print(arr**2) # 幂运算[ 4 16 36 64 100] print(arr/2) # 除法 [1. 2. 3. 4. 5.] print(arr.max()) # 元素中的最大值 10 print(arr.min()) # 元素中的最小值 2 print(arr.mean()) # 元素的平均值 6.0 print(arr.sum(),np.sum(arr)) # 元素的总和 30 30 print(arr.std()) # 元素的标准差 2.8284271247461903 print(arr.var()) # 元素的方差 8.0
②数组之间的数学运算
如果两个数组纬度相同,即arr1.shape = arr2.shape,他们之间的数学运算就是每一个对应的元素进行运算,如果形状不同,则会触发广播机制,具体见菜鸟教程https://www.runoob.com/numpy/numpy-broadcast.html
五、随机数
1.random.normal()
生成[0,1)之间标准正态分布的随机浮点数,无参数生成一个随机数,有参数需要用括号括起来。
arr1 = np.random.normal() arr2 = np.random.normal(size = 2) arr3 = np.random.normal(size = (2,3)) print(arr1) print(arr2) print(arr3) # 1.1511731857477647 # [1.00477836 1.88009993] # [[ 0.44901815 -1.09567036 -0.29054339] # [-0.98372232 0.40854306 1.63187907]]
2.random.rand()
生成[0,1)之间的均匀分布的随机浮点数,无参数生成一个随机数,有参数直接使用(m,n)即可
arr1 = np.random.rand() arr2 = np.random.rand(2) arr3 = np.random.rand(2,3) print(arr1) print(arr2) print(arr3) # 0.583667212009531 # [0.15508024 0.23161194] # [[0.11583745 0.92588869 0.69102494] # [0.49288564 0.42045576 0.42541661]]
3.random.randn()
生成正态分布的随机浮点数,大小无限制,无参数生成一个随机数,有参数直接使用(m,n)即可
arr1 = np.random.randn() arr2 = np.random.randn(2) arr3 = np.random.randn(2,3) print(arr1) print(arr2) print(arr3) # 2.263955408625279 # [ 0.15676236 -0.15578064] # [[ 2.30273663 -0.75283754 -0.46872555] # [-1.14051476 1.51395796 -1.39675718]]
4.random.randint()
使用方法random.randint(start,stop,shape,dtype)
生成的数组纬度为参数shape,纬度默认为1,
如果start和stop都存在则start<= 元素 <stop且要求start < stop,如果只传入一个参数则0 <= 元素 < 参数
arr1 = np.random.randint(5) #生成一个随机整数,范围在[0,5)之间 arr2 = np.random.randint(0,10) #生成一个随机整数,范围在[0,10)之间 arr3 = np.random.randint(0,10,5) #生成一个包含5个元素的一维数组,元素范围在[0,10)之间 arr4 = np.random.randint(0,10,[2,5])#生成一个2行、5列的二维数组,元素范围在[0,10)之间 print(arr1) print(arr2) print(arr3) print(arr4) # 4 # 8 # [4 7 6 3 9] # [[4 7 4 7 1] # [2 0 8 9 3]]
5.random.uniform()
使用方法random.uniform(min,max,shape),均匀生成形状为shape、大小介于min和max之间的数组
arr1 = np.random.uniform(-5,5) arr2 = np.random.uniform(-5,5,10) arr3 = np.random.uniform(-5,5,(2,5)) print(arr1) print(arr2) print(arr3) # 1.4332287676136222 # [-3.80524427 -2.12707058 0.0591455 1.00699272 -0.18934898 -4.66894326 -1.44132482 2.80757844 -0.2869196 -4.83401471] # [[-3.01349008 -0.28137982 1.40406868 -4.71398305 -0.58511982] # [-1.62481178 3.24231459 0.10724101 -1.99657278 -2.8664592 ]]
6.random.RandomState(n)
上述几种生成随机数的方法,如果直接使用,即使是同一个程序,每次运行都会生成不同的随机数。
使用rng = np.random.RandomState(n)生成随机数种子,再通过种子rng去调用normal()、rand()、randn()、randint()。
参数n表示使用第几套种子,对于一个随机数发生器,只要种子相同,生成的随机数序列总是相同的。
六、写入和读取文件
1.save()和load()
使用方法:save('文件名',arr),load('文件名'),文件类型为.npy
save()保存的文件默认后缀名.npy,如果传入的文件名以.npy结尾那么保存的文件名即为传入的文件名,如果不以.npy结尾保存时会自动在文件名后加后缀.npy
由于save()保存的文件类型为npy,因此直接打开会显示为乱码,需要通过load()查看内容。
arr = np.random.randint(0,5,[2,5]) np.save('testNumpy.npy',arr) arr_load = np.load('testNumpy.npy') print(arr_load) # [[0 0 1 4 2] # [2 3 4 2 0]]
2.savetxt()和loadtxt()
使用方法:savetxt('文件名',arr,delimiter=',',fmt='%.2f'),loadtxt('textNumpy.text',delimiter=','),其中delimiter指定txt文件中元素的分隔符,fmt指定数值保留的格式。
arr = np.random.rand(10,10) np.savetxt('textNumpy.text',arr,delimiter=',',fmt='%.2f') arr_load = np.loadtxt('textNumpy.text',delimiter=',') print(arr_load)
由于保存的文件为txt类型,因此生成的文件可以直接打开,文件内以指定的delimiter保存数据,无数组的[ ],通过loadtxt( )可读取。