numpy基础学习 numpy模块是学习数据分析和深度学习必须学习的内容,一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算,所以本篇文章主要讲解一下numpy的基础内容
官网👉https://numpy.org/
numpy创建矩阵 一般创建矩阵使用比较多的就是array、ones等函数,下面展示一些部分创建矩阵的用法
1 2 3 4 5 6 7 8 9 10 11 import numpy as npa = np.array([1 , 2 , 3 , 4 , 5 ]) b = np.array(range (1 , 6 )) c = np.arange(1 , 6 ) d = np.asarray([1 , 2 , 3 , 4 , 5 ]) print ('a' , a, type (a), a.dtype)print ('b' , b, type (b), b.dtype)print ('c' , c, type (c), c.dtype)print ('d' , d, type (d), d.dtype)
结果展示
1 2 3 4 5 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py a [1 2 3 4 5] <class 'numpy.ndarray'> int32 b [1 2 3 4 5] <class 'numpy.ndarray'> int32 c [1 2 3 4 5] <class 'numpy.ndarray'> int32 d [1 2 3 4 5] <class 'numpy.ndarray'> int32
上面的展示结果说明a、b、c、d
内容的展示,其中a、b、c、d
的内容都是1,2,3,4,5
,其中a、b、c、d
的类型是numpy.ndarray
,其中每个元素的类型是int32
numpy中常见的数据类型 numpy常见的数据类型表展示如下
名称
描述
bool_
布尔型数据类型(True 或者 False)
int_
默认的整数类型(类似于 C 语言中的 long,int32 或 int64)
intc
与 C 的 int 类型一样,一般是 int32 或 int 64
intp
用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)
int8
字节(-128 to 127)
int16
整数(-32768 to 32767)
int32
整数(-2147483648 to 2147483647)
int64
整数(-9223372036854775808 to 9223372036854775807)
uint8
无符号整数(0 to 255)
uint16
无符号整数(0 to 65535)
uint32
无符号整数(0 to 4294967295)
uint64
无符号整数(0 to 18446744073709551615)
float_
float64 类型的简写
float16
半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
float32
单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
float64
双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
complex_
complex128 类型的简写,即 128 位复数
complex64
复数,表示双 32 位浮点数(实数部分和虚数部分)
complex128
复数,表示双 64 位浮点数(实数部分和虚数部分)
数据类型的相关操作
1 2 3 4 5 6 7 8 9 import numpy as npa = np.array([1 , 0 , 1 , 0 ], dtype=np.bool_) print ('a' , a, type (a), a.dtype)b = a.astype(np.int8) print ('b' , b, type (b), b.dtype)
结果展示
1 2 3 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py a [ True False True False] <class 'numpy.ndarray'> bool b [1 0 1 0] <class 'numpy.ndarray'> int8
浮点数的相关操作
1 2 3 4 5 6 7 8 9 10 import numpy as npa = np.random.normal(1.75 , 1 , 10 ) print ('a' , a, type (a), a.dtype)b = np.round (a, 2 ) print ('b' , b, type (b), b.dtype)
结果展示
1 2 3 4 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py a [ 1.13844152 1.2766936 0.99489152 2.03742641 3.27012804 0.6785755 0.39133123 0.44052134 -0.38859551 1.39006692] <class 'numpy.ndarray'> float64 b [ 1.14 1.28 0.99 2.04 3.27 0.68 0.39 0.44 -0.39 1.39] <class 'numpy.ndarray'> float64
数组的形状 numpy数组有不同的形状,有时候理解起来可能有些难以理解。特别是维度多了之后就比较晃眼,不过一般理解3维以内的就可以了。
比如这个三维数组(看有几个左括号就是几个维度),怎么看出形状呢
1 [[[1,2,3],[1,2,3],[1,2,3]],[[1,2,3],[1,2,3],[1,2,3]]]
首先是看最里面那个[1,2,3]
有三个元素,所以是3
其次是看这个[[1,2,3],[1,2,3],[1,2,3]]
,有三个[1,2,3]
元素,所以是3
最终看[[[1,2,3],[1,2,3],[1,2,3]],[[1,2,3],[1,2,3],[1,2,3]]]
,有两个[[1,2,3],[1,2,3],[1,2,3]]
,所以是2
综上这个数组的形状是(2,3,3)
数组形状操作
1 2 3 4 5 6 7 8 import numpy as npa = np.array([[3 , 4 , 5 , 6 , 7 , 8 ], [4 , 5 , 6 , 7 , 8 , 9 ]]) print (a)print ("a的形状" , a.shape)b = a.reshape(3 , 4 ) print (b)print ("b的形状" , b.shape)
结果展示
1 2 3 4 5 6 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py [[3 4 5 6 7 8] [4 5 6 7 8 9]] (2, 6) [[3 4 5 6 7 8] [4 5 6 7 8 9]]
数组的轴 数组的轴在numpy中可以理解为方向,使用0,1,2…数字表示,对于一个一维数组,只有一个0轴,对于2维数组(shape(2,2)),有0轴和1轴,对于三维数组(shape(2,2, 3)),有0,1,2轴。
有了轴的概念之后,我们计算会更加方便,比如计算一个2维数组的平均值,必须指定是计算哪个方向上面的数字的平均值
如:
1 2 arr = np.random.randn(4 ,3 ) arr_mean = arr.mean(0 )
图解:
数组相关的计算操作 数组和算的计算相关操作 1 2 3 4 5 6 7 8 import numpy as npa = np.array([[3 , 4 , 5 , 6 , 7 , 8 ], [4 , 5 , 6 , 7 , 8 , 9 ]]) print ("a的值\n" , a)b = a + 1 print ("a+1的值\n" , b)c = a * 3 print ("a*3的值\n" , c)
结果展示如下,可以看到都是在每个位置上进行对应的操作,这个其实是numpy当中的广播机制
1 2 3 4 5 6 7 8 9 10 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py a的值 [[3 4 5 6 7 8] [4 5 6 7 8 9]] a+1的值 [[ 4 5 6 7 8 9] [ 5 6 7 8 9 10]] a*3的值 [[ 9 12 15 18 21 24] [12 15 18 21 24 27]]
数组和数组的相关计算,数组维度相同时 1 2 3 4 5 6 7 8 9 import numpy as npa = np.array([[3 , 4 , 5 , 6 , 7 , 8 ], [4 , 5 , 6 , 7 , 8 , 9 ]]) print ("a的值\n" , a)b = a * 3 print ("b的值\n" , b)print ("a+b的值\n" , a + b)print ("a-b的值\n" , a - b)print ("a*b的值\n" , a * b)
结果展示如下,可以看到数组相乘是对应元素的乘积,与线性代数当中的矩阵相乘不一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py a的值 [[3 4 5 6 7 8] [4 5 6 7 8 9]] b的值 [[ 9 12 15 18 21 24] [12 15 18 21 24 27]] a+b的值 [[12 16 20 24 28 32] [16 20 24 28 32 36]] a-b的值 [[ -6 -8 -10 -12 -14 -16] [ -8 -10 -12 -14 -16 -18]] a*b的值 [[ 27 48 75 108 147 192] [ 48 75 108 147 192 243]]
数组和数组的相关计算,数组维度不同时 两个数组维度不用时,numpy当中会有一个著名的广播机制,具体的讲解可以查看https://www.cnblogs.com/jiaxin359/p/9021726.html 这篇文章的讲解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import numpy as npa = np.array([[3 , 4 , 5 , 6 , 7 , 8 ], [4 , 5 , 6 , 7 , 8 , 9 ]]) print ("a的值\n" , a)b = np.array([1 , 2 , 3 , 4 , 5 , 6 ]) print ("b的值\n" , b)print ("a+b的值\n" , a + b)print ("a-b的值\n" , a - b)print ("a*b的值\n" , a * b)c = np.array([[1 ], [2 ]]) print ("c的值\n" , c)print ("a+c的值\n" , a + c)print ("a-c的值\n" , a - c)print ("a*c的值\n" , a * c)
结果如下,可以看到b是沿着轴0上进行广播,而c是沿着轴1上进行广播的
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 27 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py a的值 [[3 4 5 6 7 8] [4 5 6 7 8 9]] b的值 [1 2 3 4 5 6] a+b的值 [[ 4 6 8 10 12 14] [ 5 7 9 11 13 15]] a-b的值 [[2 2 2 2 2 2] [3 3 3 3 3 3]] a*b的值 [[ 3 8 15 24 35 48] [ 4 10 18 28 40 54]] c的值 [[1] [2]] a+c的值 [[ 4 5 6 7 8 9] [ 6 7 8 9 10 11]] a-c的值 [[2 3 4 5 6 7] [2 3 4 5 6 7]] a*c的值 [[ 3 4 5 6 7 8] [ 8 10 12 14 16 18]]
数组的拼接 拼接相关的函数有许多,列出下面的几个函数
函数
介绍
concatenate
提供了axis参数,用于指定拼接方向
append
默认先ravel再拼接成一维数组,也可指定axis
stack
提供了axis参数,用于生成新的维度
vstack
垂直拼接,沿着列的方向,对行进行拼接
hstack
水平拼接,沿着行的方向,对列进行拼接
dstack
沿着第三个轴(深度方向)进行拼接
concatenate 1 2 3 4 5 6 7 8 9 10 11 import numpy as npa = np.array([[1 , 2 ], [3 , 4 ]]) print ('数组a\n' , a)b = np.array([[5 , 6 ]]) print ('数组b\n' , b)c = np.array([[5 ], [6 ]]) print ('数组c\n' , b)print ('在轴0上拼接\n' , np.concatenate((a, b), axis=0 ))print ('在轴1上拼接\n' , np.concatenate((a, c), axis=1 ))print ('不指定轴上拼接\n' , np.concatenate((a, b), axis=None ))
结果展示,可以看到对于0轴和1轴上的连接是不同的,并且如果不指定轴就是变成一维
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py 数组a [[1 2] [3 4]] 数组b [[5 6]] 数组c [[5 6]] 在轴0上拼接 [[1 2] [3 4] [5 6]] 在轴1上拼接 [[1 2 5] [3 4 6]] 不指定轴上拼接 [1 2 3 4 5 6]
append 1 2 3 4 5 6 7 8 9 10 11 import numpy as npa = np.array([[1 , 2 ], [3 , 4 ]]) print ('数组a\n' , a)b = np.array([[5 , 6 ]]) print ('数组b\n' , b)c = np.array([[5 ], [6 ]]) print ('数组c\n' , b)print ('在轴0上拼接\n' , np.append(a, b, axis=0 ))print ('在轴1上拼接\n' , np.append(a, c, axis=1 ))print ('不指定轴上拼接\n' , np.append(a, b))
结果展示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py 数组a [[1 2] [3 4]] 数组b [[5 6]] 数组c [[5 6]] 在轴0上拼接 [[1 2] [3 4] [5 6]] 在轴1上拼接 [[1 2 5] [3 4 6]] 不指定轴上拼接 [1 2 3 4 5 6]
stack stack函数比较复杂,以后再补上
vstack、hstack和dstack vstack、hstack和dstack分别代表垂直拼接、水平拼接和深度拼接
1 2 3 4 5 6 7 8 9 import numpy as npa = np.array((1 , 2 , 3 )) print ('数组a\n' , a)b = np.array((4 , 5 , 6 )) print ('数组b\n' , b)print ('垂直拼接\n' , np.vstack((a, b)))print ('水平拼接\n' , np.hstack((a, b)))print ('深度拼接\n' , np.dstack((a, b)))
结果展示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py 数组a [1 2 3] 数组b [4 5 6] 垂直拼接 [[1 2 3] [4 5 6]] 水平拼接 [1 2 3 4 5 6] 深度拼接 [[[1 4] [2 5] [3 6]]]
可能水平和垂直比较好理解,那个深度拼接(第三个维度)就比较难以理解了,在官方文档上的解释是这等效于在形状 (M,N) 的二维阵列被重新整形为 (M,N,1) 并且形状 (N,) 的一维阵列被重新整形为 (1, N,1)。重建除以 dsplit 的数组
。也就是是说二维数组和一维数组都会被重新reshape成三维数组。所以出现了上面的结果
numpy索引和切片 numpy中索引和切片和python原生的list是相同的
1 2 3 4 5 6 7 8 9 10 11 12 import numpy as npa = np.arange(24 ).reshape((4 , 6 )) print ('展示a\n' , a)print ("取一行" , a[0 ])print ("取一列" , a[:, 2 ])print ("取多行\n" , a[0 :2 ])print ("取多列\n" , a[:, 0 :2 ])print ("取多行多列\n" , a[0 :3 , 0 :3 ])print ("使用数组索引\n" , a[[0 , 1 , 2 ], [0 , 1 , 0 ]])print ("使用数组索引\n" , a[[0 , 0 , 3 , 3 ], [0 , 2 , 0 , 2 ]])print ("使用数组索引\n" , a[[[0 , 0 ], [3 , 3 ]], [[0 , 2 ], [0 , 2 ]]])
结果展示,可以发现数组索引的维度会对返回后的维度产生影响
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 27 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py 展示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]] 取一行 [0 1 2 3 4 5] 取一列 [ 2 8 14 20] 取多行 [[ 0 1 2 3 4 5] [ 6 7 8 9 10 11]] 取多列 [[ 0 1] [ 6 7] [12 13] [18 19]] 取多行多列 [[ 0 1 2] [ 6 7 8] [12 13 14]] 使用数组索引 [ 0 7 12] 使用数组索引 [ 0 2 18 20] 使用数组索引 [[ 0 2] [18 20]]
numpy当中还可以使用布尔索引
1 2 3 4 5 6 7 import numpy as npa = np.arange(24 ).reshape((4 , 6 )) print ('展示a\n' , a)b = a < 10 print ("展示b\n" , b)print ("使用布尔索引\n" , a[b])
结果展示
1 2 3 4 5 6 7 8 9 10 11 12 13 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py 展示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]] 展示b [[ True True True True True True] [ True True True True False False] [False False False False False False] [False False False False False False]] 使用布尔索引 [0 1 2 3 4 5 6 7 8 9]
numpy中的nan和inf nan(NAN,Nan):not a number表示不是一个数字
什么时候numpy中会出现nan?
当我们读取本地的文件为float的时候,如果有缺失,就会出现nan,或者当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大)
inf(-inf,inf):infinity,inf表示正无穷,-inf表示负无穷
什么时候回出现inf包括(-inf,+inf)?
比如一个数字除以0,(python中直接会报错,numpy中是一个inf或者-inf)
1 2 3 4 5 6 import numpy as npa = np.inf b = np.nan print (type (a)) print (type (b))
nan需要注意的点
两个nan是不相等的
1 2 np.nan==np.nan np.nan!=np.nan
任何值和nan进行计算都是nan
判断数组中nan的个数我们可以使用np.count_nonzero(t!=t)
进行
改变数组中nan的值也可以使用t[np.isnan(t)] = 0
进行
其他 numpy当中三元运算符where
1 2 3 4 5 6 7 import numpy as npa = np.arange(10 ) print ('a的值\n' , a)print (np.where(a < 5 , a, 10 * a))
结果展示
1 2 3 4 D:\ProgramData\Anaconda3\python.exe E:/work_space/shixi/Problem/Test.py a的值 [0 1 2 3 4 5 6 7 8 9] [ 0 1 2 3 4 50 60 70 80 90]
numpy当中经常使用的统计函数有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 求和:t.sum(axis=None) 均值:t.mean(a,axis=None) 受离群点的影响较大 中值:np.median(t,axis=None) 最大值:t.max(axis=None) 最小值:t.min(axis=None) 极值:np.ptp(t,axis=None) 即最大值和最小值差 标准差:t.std(axis=None) 获取最大值最小值的位置 np.argmax(t,axis=0) np.argmin(t,axis=1) 创建一个全0的数组: np.zeros((3,4)) 创建一个全1的数组:np.ones((3,4)) 创建一个对角线为1的正方形数组(方阵)np.eye(3)