python中numpy库的简单使用
一、Numpy介绍
NumPy是Python中科学计算的基础包,它的核心是 ndarray(多维数组)对象,简称数组。数组由同种类型的元素组成,可以通过整数元组进行索引。在Numpy中,维度称为轴(axis),轴的个数称为秩(rank).。比如[1,2,3]是一维数组,具有一个轴,由3个元素组成,即它的长度为3。二维数组由1或多个一维数组组成,比如[[1,2,3],[2,3,4]]。三维数组由1或多个二维数组组成,以此类推。
二、安装
pip install numpy
三、数组创建
-
np.array()
>>> import numpy as np >>> np.array([1,2,3],dtype=int) #创建一维数组,可指定元素类型 array([1, 2, 3]) >>> np.array([[1,2,3],[4,5,6]]) #创建二维数组 array([[1, 2, 3], [4, 5, 6]]) #同理创建多维数组
-
np.random.rand(m,n)或者np.random.random((m,n))------创建m行n列,由0-1的随机数构成的数组,注意后者传入的参数是一个元组
>>> np.random.rand(2,3) array([[0.96520381, 0.3969341 , 0.36751751], [0.33390612, 0.46732563, 0.54680012]])
-
np.arange(start,stop,step)------创建一维数组,用法同python中的range
>>> np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> np.arange(1,10) #左闭右开区间 array([1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> np.arange(1,10,2)#指定步幅为2 array([1, 3, 5, 7, 9]) -
np.linspace(start,stop,num)------指定起止值,创建指定个数的等差一维数组
>>> np.linspace(10,100,6) array([ 10., 28., 46., 64., 82., 100.])
-
np.ones((m,n))-----------创建一个m行n列的全1数组
>>> np.ones((3,4)) array([[1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.]])
-
np.zeros((m,n))--------------创建一个m行n列的全0数组
>>> np.zeros((2,3)) array([[0., 0., 0.], [0., 0., 0.]])
-
np.indices((m,n))---------创建m行,n列的3维数组;如果参数元组内传入i个元素,则创建(i+1)维数组,内部元素为i个i维数组
>>> np.indices((2,3)) array([[[0, 0, 0], [1, 1, 1]], [[0, 1, 2], [0, 1, 2]]])
四、数组堆叠与拆分
-
堆叠
-
np.vstack() - 行堆叠
-
np.hstack() - 列堆叠
>>> m array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> n array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) >>> np.vstack((m,n)) array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]]) >>> np.hstack((m,n)) array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
-
-
拆分
-
np.vsplit() - 行拆分,即沿垂直轴拆分,可以指定平均拆分成几等分,也可以通过元组中的元素来指定从哪些行后面进行拆分
-
np.hsplit() - 列拆分,即沿水平轴拆分,可以指定平均拆分成几等分,也可以通过元组中的元素来指定从哪些列后面进行拆分
>>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> np.vsplit(a,3) #按行拆分成3等分 [array([[0, 1, 2, 3, 4]]), array([[5, 6, 7, 8, 9]]), array([[10, 11, 12, 13, 14]])] >>> np.vsplit(a,(2,)) #从第2行后面进行拆分 [array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]), array([[10, 11, 12, 13, 14]])] >>> np.hsplit(a,5) #按列拆分成5等分 [array([[ 0], [ 5], [10]]), array([[ 1], [ 6], [11]]), array([[ 2], [ 7], [12]]), array([[ 3], [ 8], [13]]), array([[ 4], [ 9], [14]])] >>> np.hsplit(a,(2,3)) #分别从第二列和第3列后进行拆分 [array([[ 0, 1], [ 5, 6], [10, 11]]), array([[ 2], [ 7], [12]]), array([[ 3, 4], [ 8, 9], [13, 14]])]
-
五、运算
-
算数运算:+,-,*,/,//,%,**-------------每个数组中对应元素进行运算
>>> a = np.array([1,2,3,4]) >>> b = np.array([5,6,7,8]) >>> a+b array([ 6, 8, 10, 12]) >>> a-b array([-4, -4, -4, -4]) >>> a*b array([ 5, 12, 21, 32]) >>> a/b array([0.2 , 0.33333333, 0.42857143, 0.5 ]) >>> a//b array([0, 0, 0, 0]) >>> a%b array([1, 2, 3, 4]) >>> a**2 array([ 1, 4, 9, 16])
-
比较运算:==,<,<=,>,>=,!=----------------------数组中每个元素都进行相应比较,返回bool值组成的数组
>>> a array([1, 2, 3, 4]) >>> a==2 array([False, True, False, False]) >>> a>2 array([False, False, True, True]) >>> a>=2 array([False, True, True, True])
-
逻辑运算:逻辑与(&),逻辑或(|),逻辑非(~)
>>> a = np.arange(15).reshape(3,5) >>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> (a>3)&(a<10) array([[False, False, False, False, True], [ True, True, True, True, True], [False, False, False, False, False]]) >>> (a<3)|(a>10) array([[ True, True, True, False, False], [False, False, False, False, False], [False, True, True, True, True]])
>>> a[~(a%2==0)]
array([ 1, 3, 5, 7, 9, 11, 13])
-
六、索引和切片
-
一维数组
-
同python列表操作一样
-
x[i]---x数组中索引为i的元素,索引从0开始
-
x[-i]---索引倒数第i个元素
-
x[m:n]--不包含索引为n的元素
-
x[m:n:i]--指定步幅为i
>>> a = np.arange(10) >>> a array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> a[2] 2 >>> a[-1] 9 >>> a[3:8] array([3, 4, 5, 6, 7]) >>> a[3:8:2] array([3, 5, 7])
-
-
多维数组
-
每个轴可以有一个索引。这些索引以逗号分隔的元组给出,当提供的索引少于轴的数量时,缺失的索引被认为是完整的切片
:
-
以二维数组为例:
>>> a array([[ 1, 2, 3, 4], [ 10, 20, 30, 40], [100, 200, 300, 400]]) >>> a[2] #取第3行数据 array([100, 200, 300, 400]) >>> a[:,2] #取第3列数据 array([ 3, 30, 300]) >>> a[0:2,2] #取前2行第3个数 array([ 3, 30]) >>> a[1,2] #取第2行第3个数 30
-
-
索引数组
-
单个索引数组
-
只对第1个维度进行索引操作
-
结果形式:将索引数组里面的每个索引值,替换成数组被该索引值所索引的结果
-
以x数组为例,索引数组为一维数组np.array([1,1,3,4]),那么x[np.array([1,2,3,4])]----结果为array([x[1],x[1],x[3],x[4]])
-
以x数组为例,索引数组为二维数组[[1,1],[3,4]],那么x[[[1,1],[3,4]]]----结果为[[x[1],x[1]],[x[3],x[4]]]
>>> a = np.linspace(2,20,10,dtype=int) >>> a array([ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]) >>> a[[1,2,3,4]] #传入列表索引和一维数组索引等效 array([ 4, 6, 8, 10]) >>> a[np.array([1,2,3,4])] #索引数组为一维数组 array([ 4, 6, 8, 10]) >>> a[np.array([[1,2],[3,4]])]#索引数组为二维数组 array([[ 4, 6], [ 8, 10]])
-
多个索引数组
-
为多个维度提供索引,每个维度的索引数组必须具有相同的形状 。
>>> a = np.indices((2,3)) #创建一个3维数组 >>> a array([[[0, 0, 0], [1, 1, 1]], [[0, 1, 2], [0, 1, 2]]]) >>> a[np.array([0,1]),np.array([0,1])] #对前两个维度进行索引,结果相当于np.array([a[0][0],a[1][1]]) array([[0, 0, 0], [0, 1, 2]]) >>> a[np.array([0,1]),np.array([0,1]),np.array([1,2])] #对3个维度分别索引,结果相当于np.array(a[0][0][1],a[1][1][2]) array([0, 2])
-
-
-
索引数组和整数相结合
-
将整数理解为和索引数组等长的以该整数为元素的数组
>>> a = np.array([[1,2,3],[2,3,4],[3,4,5]]) >>> a array([[1, 2, 3], [2, 3, 4], [3, 4, 5]]) >>> a[np.array([1,2]),2] array([4, 5]) >>> a[np.array([1,2]),np.array([2,2])] array([4, 5]) >>> a[1,np.array([1,2])] array([3, 4]) >>> a[[1,1],np.array([1,2])] array([3, 4])
-
-
布尔索引
-
与原始数组具有相同形状的布尔数组
-
在获取元素的时候,只返回索引值为True的元素所组成的数组,其它元素舍弃
>>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> b = a > 3 >>> b array([[False, False, False, False, True], [ True, True, True, True, True], [ True, True, True, True, True]]) >>> a[b] #返回a中大于3的元素所组成的数组 array([ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) >>> a[b] = 0 #赋值,只对索引数组中元素为True的位置进行赋值 >>> a array([[0, 1, 2, 3, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]])
-
-
对于数组的每个维度,给出一个一维布尔数组以及想要的切片
-
请注意,一维布尔数组的长度必须与要切片的尺寸(或轴)的长度一致
>>> a = np.arange(15).reshape((3,5)) >>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> b1 = np.array([True,False,True]) >>> b2 = np.array([True,False,True,False,True]) >>> a[b1,:] array([[ 0, 1, 2, 3, 4], [10, 11, 12, 13, 14]]) >>> a[:,b2] array([[ 0, 2, 4], [ 5, 7, 9],
-
-
七、数组常用属性和方法
-
常用属性
-
ndim - 数组的轴(维度)的个数
-
shape - 数组的维度。这是一个整数的元组,表示每个维度中数组的大小。对于m行n列的矩阵数组,返回的是(m,n)
-
size - 数组中所有元素的个数,等于shape的元素的乘积
-
dtype - 数组中元素类型的对象,可以继续通过该对象的name属性来获取元素类型的名称
-
itemsize - 数组中每个元素的字节大小,比如元素类型为int64的数组,每个元素的字节大小为64/8=8个字节
-
T - 转置操作,不修改原数组
>>> a = np.arange(15).reshape((3,5)) >>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> a.ndim 2 >>> a.shape (3, 5) >>> a.size 15 >>> a.dtype dtype('int64') >>> a.dtype.name 'int64' >>> a.itemsize 8 >>> a.T array([[ 0, 5, 10], [ 1, 6, 11], [ 2, 7, 12], [ 3, 8, 13], [ 4, 9, 14]])
-
-
常用方法
-
tolist() - 转换成python列表
-
astype(类型) - 转换数组元素类型
-
min() - 求所有元素最小值,返回单个值
-
max() - 求所有元素最大值
-
sum() - 求总和
-
mean() - 求平均值
-
min(axis) - 参数axis=1,按行求最小值,axis=0,按列求最小值,返回数组类型
-
max(axis) - 同上,求最大值
-
mean(axis=None) - 同上,求均值
-
argmin() - 求最小值所对应的索引值,如果是多维数组,则为拆分为一维数组后的索引值
-
argmin(axis) - 参数axis=1,按行求最小值所对应的索引值,axis=0,按列求最小值所对应的索引值,返回数组类型
-
argmax() - 同上,求最大值对应索引值
-
argmax(axis) - 同上,求最大值对应索引值,返回数组类型
-
view() - 视图,浅拷贝
-
copy()- 深拷贝
-
reshape() - 修改数组形状,但不会修改原数组,比如reshape(m,n)表示修改原数组为m行n列的二维数组
-
resize() - 修改数组形状,并且会修改原数组
-
ravel() - 返回数组降维后的一维数组,但不会修改原数组
-
flatten() - 同ravel(),返回数组降维后的一维数组,但不会修改原数组
>>> a = np.arange(15) #创建一个一维数组 >>> a array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) >>> a.tolist() #转成python列表形式 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] >>> a.astype(float) #转换数组元素类型为float类型 array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14.]) >>> b = a.reshape(3,5) #修改数组为3行5列的二维数组 >>> b array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> a #reshape后,没有修改原数组 array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) >>> a.resize(3,5) #resize修改了原数组 >>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> a.max() #返回数组内元素最大值 14 >>> a.argmax() #返回最大值在一维数组中的索引值 14 >>> a.argmax(axis=1) #按行求最大值所对应的索引值 array([4, 4, 4]) >>> a.ravel() #降维成一维数组 array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) >>> a.flatten() #降维成一维数组 array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) >>> a #ravel()和flatten()都没有修改原数组 array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> c = a.copy() #对a进行深拷贝 >>> d = a.view() #对a进行浅拷贝 >>> c array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> d array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> c[c==1] = 1111 #将深拷贝过的c数组中元素1修改为1111 >>> d[d==2] = 222 #将浅拷贝过的d数组中元素2修改为222 >>> a #修改浅拷贝过的数组,a数组中的元素发生相应变化 array([[ 0, 1, 222, 3, 4], [ 5, 6, 7, 8, 9], [ 10, 11, 12, 13, 14]])
-
以上介绍的只是numpy的部分知识,想深入了解numpy,可参考numpy中文文档