文章目录
摸索了半天才把numpy库下好,太难了
一.简介
1.Numpy作用
numpy的全称是Numerical Python(本文全部使用小写,貌似应该写成NumPy这样,但是这不重要),是Python的一个扩展程序库,它不仅针对数组运算提供了大量的函数库,而且它还能够支持维度数组与矩阵运算。是处理大量数组类结构和机器学习框架的基础库!
2.库的导入
导入numpy库,通常将其命名为缩写np
import numpy as np
下面这种写法更方便,但是若库之间有冲突的函数名会报错,所以不推荐:
from numpy import *
3.数组的属性
①数组的形状(shape)描绘了数组的维度,由元组来表示,比如(2,3)代表了2行3列的数组。可以利用a.shape来查看数组变量a的形状
②元素总个数,可以用size进行查询
③元素数据类型,可以用dtype进行查询
二.数组的生成
1.array函数
利用array函数将对象转化为数组
例:
L=[x**2 for x in range(1,10,2)]
a=np.array(L)
将列表L转化为了数组
此外还可以利用参数dtype和ndmin指定数据类型和维度:
L=[2,3,4,5]
a=np.array(L,dtype=float,ndmin=2)
输出:
[[2. 3. 4. 5.]]
因为列表只有一维,但array函数中指定ndmin=2,所以生成了二维数组
要注意列表必须要满足数组的形式才能进行转换,如下编译器会报错:
a = np.array([ [2,4],[2 ,3,4,5] ])
因为第一行有2个元素,第二行有4个元素,不符合数组的形式,所以编译器会报错
2.zeros及ones函数-全0、1数组
利用ones和zeros函数可以实现全0数组、全1数组的创建
参数为数组的形状,也可以用dtype指定数组元素的数据类型(默认为float)
例:
a=np.zeros((2,3),dtype='int')
创建了两行三列的数组,元素全部为int型的0
ones函数使用方法相同
3.empty函数-空数组
利用empty函数创建一个未初始化的数组,数组元素初始值为随机值,参数为数组形状, 可以用type指定数据类型
4.arange函数
arange函数和range函数很像,生成一个整数序列,四个参数:
start、stop、step、dtype分别为起点,终点、步长、元素类型,[start,stop)为前开后闭区间
例:
a=np.arange(1,10,3,'float')
输出:
[1. 4. 7.]
5.linspace函数-等差数列
linspace函数用于生成等差数列,参数为start、stop、num(默认为50),分别为起点、终点、个数
该函数不需要指定等差(否则相当于步长,用arange函数就可以生成),它生成的是第一个元素为start,最后一个元素为stop的,元素个数为num的等差数列,即会自动计算出等差
例:
a=np.linspace(1,2,10)
生成的数列为:
[1. 1.11111111 1.22222222 1.33333333 1.44444444 1.55555556
1.66666667 1.77777778 1.88888889 2. ]
此外,可以用参数endpoint(默认为True)来指定数组是否包含stop,其值为True时表示包含,为False表示不包含,例:
a=np.linspace(1,2,10,endpoint=False)
生成数组:
[1. 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9]
也可以使用参数dtype来指定数组元素类型(默认为浮点型)
6.logspace函数-等比数列
利用logspace函数可以生成等比数列,参数为start、stop、num、base,和等比数列差不多,要注意base参数,表示底,因为其实该函数生成的是 b a s e s t a r t {base}^{start} basestart到 b a s e s t o p base^{stop} basestop的等比数列
num默认为50,base默认为10
endpoint用于决定数组是否包含 b a s e s t o p base^{stop} basestop
例:
a=np.logspace(0,10,10,endpoint=False,base=2)
生成:
[ 1. 2. 4. 8. 16. 32. 64. 128. 256. 512.]
7.random函数-随机数
random中包含很多生成随机数的函数
比如random.rand(dn) 参数为生成随机数的个数,可以在0到1之间生成随机数,类型为浮点型
random.randn(dn) 可以生成满足标准正态分布的随机数序列
random.randint(low,high,size)可以从low到high生成size个随机的整数序列
……
三.数组的运算
1.数学运算
以两个形状相同的数组为运算对象时:
a+b表示a和b对应位置上元素的相加而不是两个数组的拼接(与列表不同),例:
a=np.array([1,2,3,4,5])
b=np.array([2,3,3,4,5])
print(a+b)
输出:
[ 3 5 6 8 10]
同理,其它算术运算符(+、-、*、**、\、\\)也是相应位置上的元素进行运算
2.比较运算
同理,对数组执行比较运算会得到一个布尔数组:
例:
L=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])
print(L>10)
输出:
[[False False False False]
[False False False False]
[False False True True]
[ True True True True]]
四.数组的索引与切片
1.索引
数组支持用索引来查询及修改数组对应位置的值,并且支持负索引
例:
a=np.random.rand(5)
a[0]=0.2
a[-1]=0.3
print(a[2])
多维数组的索引支持以下两种方式:
①a[1][3]
②a[1,3]
都可以访问数组a第二行第四列的元素
一种比较高级的用法:
a=np.array([[1,2,3,4],[1,2,3,5]])
print(a[a>3])
输出数组a中所有大于3的元素:
[4 5]
也可以将切片与索引结合进行操作:
例:a[1:3,2]
表示第2、3行,第3列的元素
每一维都支持切片、负索引的规则
2.切片
和列表的切片一样
例:
a=np.ones((2,3),dtype=int)
a[0][1]=3
a[0][2]=0
print(a[0][1:3])
输出
[3 0]
小应用:错位相减
某电影某5天的累计票房为2000,2150,2340,2500,2700,求后四天单天的票房为多少?
因为累计票房为从第一天开始到第i天的累计值,要求得单天的票房就需要错位相减,可以利用切片操作简化这一步骤
a=np.array([2000,2150,2340,2500,2700])
print(a[1:]-a[:-1]) #a[1:]表示a[1]到a[4],a[:-1]表示a[0]到a[3]
注意数组的切片本质是引用,改变切片的值也就改变了原数组的值。
想要申请内存可以使用copy函数:
b=L[0:2].copy()
3.花式索引
切片虽然很方便,可以指定步长,但是比如说想取数组第1、5、6、12个元素,使用切片就很难实现了
数组还可以利用列表作为索引:
L=[x**2 for x in range(1,20)]
L=np.array(L)
index=[0,4,5,11] #列表index作为数组索引
print(L[index])
也可以利用元组来作为多维数组的索引:
L[(0,1,2),(0,1,2)]
第一个元组描述行,第二个元组描述列,取出了主对角线上的三个元素
需要注意的是花式索引本质是复制,而切片本质是引用,二者不一样!
五.其他函数
1.where函数
返回所有不等于0的元素的索引(返回值为元组)
这个可以和数组的比较运算结合起来,之前写过数组的比较运算返回的是一个布尔数组,而布尔数组中True为1,False为0,所以通过where函数可以得到所有布尔值为True的索引:
L=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])
print(np.where(L>10))
得到了所有元素值大于10的索引
(array([2, 2, 3, 3, 3, 3], dtype=int64), array([2, 3, 0, 1, 2, 3], dtype=int64))
2.sort函数
sort函数可以对数组进行从小到大的升序排列,注意sort函数并不改变数组,而是返回一个排好序的数组
argsort函数可以返回一个索引位置数组,数组元素为从小到大的排列在原数组中的位置
3.数组运算函数
罗列一些对数组进行运算的函数:
①sum函数对数组进行求和,有两种写法:
print(L.sum())
print(np.sum(L))
下面提到的函数大都有这两种写法:
②max函数求数组中的最大值
③min函数求数组中的最小值
④mean函数求数组值的平均值
⑤std函数求数组的标准差
4.reshape 函数
reshape函数可以改变数组的形状,可以将数组理解为矩阵。reshape函数的参数为一个元组
例:
L=np.array([[1,2,5,4],[5,6,7,8],[9,10,11,12]])
L=L.reshape(2,6)
print(L)
注意reshape函数也是不改变数组本身,而是返回一个新的数组
reshape函数要求reshape后矩阵元素个数不能变,也就是说不能将一个3行5列的数组变成2行2列的,元素个数对不上
有了reshape函数可以实现矩阵的转置(即令数组的每一个元素行列值互换)
当然,numpy库中本身就包含了两个专门用于转置的函数:
5.transpose函数
L=np.array([[1,2,5,4],[5,6,7,8],[9,10,11,12]])
print(L.T) #T好像不是函数,所以不能写成L.T()
print(np.transpose(L))
print(L.transpose())
以上三种写法都可以实现转置矩阵
6.concatenate函数
concatenate这个单词的意思是连接
concatenate函数可以实现多个数组的拼接
两个参数:第一个参数为数组名组成的元组,第二个参数为拼接的轴
axis=0,表示沿着y轴(按列)进行纵向拼接
axis=1,表示沿着x轴(按行)进行横向拼接
axis默认为0
例:
L1 = np.array([[1, 2, 5, ], [6, 7, 8]])
L2 = np.array([[0, 0], [0, 0]])
L3=np.concatenate((L1,L2),axis=1)
print(L3)
这两个数组分别为两行三列以及两行两列,所以只能按行拼接
输出:
[[1 2 5 0 0]
[6 7 8 0 0]]
Numpy库中函数非常非常多,上面只列举了一些常用的
六.task
实现一些简单的功能来练手:
①创建一个1到10的数组并逆序输出:
L=[x for x in range(1,11)]
a=np.array(L)
print(a[::-1])
采用的做法是先利用列表生成式生成1到10,然后用array函数将其转化为数组,利用切片实现逆序输出
②创建20个元素的全1矩阵,转化成4行5列的矩阵,再进行转置:
a=np.ones(20).reshape((4,5))
print(a.T)
ones函数生成全1数组,reshape函数将其变化为要求的矩阵,再转置
③创建333的随机数组
a=np.random.rand(3,3,3)
print(a)