【Python】numpy常用函数、概念、属性(一)

前言

之前做比赛、项目的时候,总是用到一个numpy函数去查一个函数,虽然有很高的效率,但是脑子中存的东西太少。最近正好选修了Python课,有讲到numpy这一节,所以我就将ppt的内容整理一下,结合我的理解,记录下常用的numpy函数。

numpy介绍

NumPy (Numerical Python) 是Python提供的的第三方库,主要用来存储和处理大型矩阵,并进行科学计算的模块。
numpy创建的数组叫做ndarray(全称:n-dimensional array object n维数组对象),其元素是同类型数据,数据存储的地址空间连续,所以进行批量操作时访问速度快。
numpy经常与SciPy(Scientific Python)和Matplotlib(绘图模块)一起使用,提供了一个强大的科学计算环境。
SciPy是一个Python算法和数学工具包,包含了最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理、图像处理等等常用计算。
Matplotlib是Python内置类型及numpy的可视化界面。利用率通用的图像用户界面工具包,比如Tkinter、wx Python,Qt等等,向应用程序嵌入式绘图提供了API。

ndarray对象的创建

注意:以下所有操作默认存在以下语句

import numpy as np

法一:array()函数

array()函数将数据源(可以是list、set、ndarray等数据结构)转换成ndarray。

# 创建一个ndarray
arr=np.array([1,2,3,4,5])
print(arr)
# 输出array([1, 2, 3, 4, 5])

如果输入数据源全是整数,那么这个ndarray中的数据类型是np.int32,可以使用dtype参数指定输入数据的类型,比如指定输入的数据在ndarray中是np.int64:

# 创建一个数据类型是int64的ndarray
arr=np.array([1,2,3],dtype=np.int64)
print(arr)
# 输出array([1, 2, 3], dtype=int64)

法二:asarray()函数

asarray()函数将数据源(可以是list、set、ndarray等数据结构)转换成ndarray。

# 创建一个ndarray
arr=np.asarray([1,2,3,4],dtype=np.float)
print(arr)
# 输出array([1., 2., 3., 4.])

asarray()和array()一样,如果输入的数据中全是整数,那么生成的ndarray中的数据默认是np.int32类型,如果存在至少一个浮点数,那么ndarray中的数据默认就是np.float64

asarray()和array()的区别:
array和asarray都可以将结构数据转化为ndarray,但是主要区别就是当数据源是ndarray时,array仍然会copy出一个副本,占用新的内存,但asarray不会,它得到的对象会和原来数据指向一个地址空间。而当数据源不是ndarray的时候,没有区别,都是将非ndarray的数据结构(比如说list、set或者tuple等)转换成ndarray对象。

法三:arange()函数

可以使用arange()函数生成一维数组。函数原型为:
numpy.arange([start],stop,[step],dtype=None),start,起始值、开区间,默认为0 ;stop,终止值,闭区间,无默认值,需要输入;step间隔,默认为1,可以是任意非零数;dtype:数据类型,可以是float\complex\int\int8\int16\int32\int64等。带[]的参数为可选参数。

>>> np.arange(3)
array([0, 1, 2])
>>> np.arange(3.0)
array([ 0.,  1.,  2.])
>>> np.arange(3,7)
array([3, 4, 5, 6])
>>> np.arange(3,7,2)
array([3, 5])

法四:ones()函数、zeros()函数、empty()函数

用法(三者非常相似):
xxx(shape,dtype),shape为创建的新ndarray的shape,dtype为创建新ndarray的元素的数据类型。

>>> arr1=np.ones((3,4))
>>> arr1
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])
>>> arr2=np.zeros((3,4),dtype=np.float64)
>>> arr2
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
>>> arr3=np.empty((3,4))
>>> arr3
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
>>> arr3=np.empty((3,4),dtype=np.int)
>>> arr3
array([[    4128860,     6029375,     3801157,     4259932],
       [    6357102,     7274595,     6553710,     3342433],
       [    7077980,     6422633, -1282408448,         572]])
>>> arr3=np.empty((3,4),dtype=list)
>>> arr3
array([[None, None, None, None],
       [None, None, None, None],
       [None, None, None, None]], dtype=object)

其中,empty函数比较特殊,它会按照输入的数据类型来初始化,如果dtype是np.float,那么初始化全部元素都是0. ;如果dtype是np.int,那么初始化为随机的整数;如果是dtype是list,那么初始化为None。

法五:使用随机函数

np.random.rand()函数
这个函数从[0,1)均匀分布中返回一个或多个样本。比如说生成2行3列数值在0和1之间的数组:

>>> arr1=np.random.rand(2,3)
>>> arr1
array([[0.88175405, 0.14383093, 0.34413505],
       [0.80448094, 0.27998358, 0.3327511 ]])

函数的参数是每一维的长度,有无限制个数的参数,所以函数源码中应该使用了*arg来接受所有参数。

np.random.randn()函数
这个函数从标准正态分布中返回一个或多个样本值。。比如说生成2行3列的正态分布数组:

>>> arr9=np.random.randn(2,3)
>>> arr9
array([[-0.11352285, -0.26890242, -1.04705918],
       [ 0.68052812, -1.47152625,  0.5052088 ]])

函数的参数含义和np.random.rand()一样。

np.random.randint()函数
此函数用于生成随机整数数组。
使用它生成2行3列的[10,20)之间的随机整数数组:

>>> arr1=np.random.randint(10,20,size=(2,3))
>>> arr1
array([[13, 13, 13],
       [15, 10, 11]])

同样,start可以省略,默认从0开始,但是end必须有。例如生成[0,20)之间的随机整数可以这样:arr1=np.random.randint(20,size=(2,3))。也同样使用dtype作为生成ndarray的元素的数据类型。

np.random.random(size)
返回指定size的[0,1)随机数数组,和np.random.rand()函数功能很相似。
例子:生成2行3列,元素值在[0,1)之间的随机数组。

>>> arr=np.random.random((2,3))
>>> arr
array([[0.92973515, 0.9029689 , 0.51673521],
       [0.26623643, 0.43050031, 0.80177883]])

np.random.random((2,3))等价于np.random.rand(2,3),实现的功能都一样。

法六:np.linspace()函数

函数原型:
np.linspace(start,stop,num,endpoint,retstep,dtype)
start,起始值,闭区间,默认0;stop,终止值,开区间,无默认值,需要输入;num是要生成的等间隔样例数量,默认为50;endpoint是否包含终止值;retstep为是否输出步长。

这个函数很有意思,和上面np.arange()函数有点像,但是arange()函数要的是步长,而这个函数要的是等间隔样例的数量

例子:
当不包含终止值stop的时候:

>>> c=np.linspace(10,20,3,endpoint=False,retstep=True,dtype='i4')
>>> c
(array([10, 13, 16]), 3.3333333333333335)

当包含终止值stop的时候:

>>> c=np.linspace(10,20,3,endpoint=True,retstep=True,dtype='f2')
>>> c
(array([10., 15., 20.], dtype=float16), 5.0)

实际上,函数先根据条件算出步长,然后根据步长计算每个数据的值(浮点数形式),再强制转换成dtype规定的数据类型。

tips:字符串i4表示的是np.int32,是一种简写形式,对应关系如下:

字符串对应的数据格式
i1np.int8
i2np.int16
i4np.int32 or np.int
i8np.int64
f2np.float16
f4np.float32
f8np.float64 or np.float

更多信息请看官网:numpy Data types

法七:np. logspace()函数

函数原型如下:
np. logspace(start,stop,num,endpoint,base,dtype)
start起始值、默认0;stop,终止值,不包含;num要生成的等间隔样例数量,默认为50;endpoint是否包含终止值;base表示底数;dtype为生成的ndarray的数据类型。

例子:

>>> x=np.logspace(10,20,num=3,endpoint=True,base=2,dtype='i4')
>>> x
array([   1024,   32768, 1048576])

结果为210,215和220,可以看到,实际上这个函数就是生成等比数列,而这个等比数列的幂为np.linspace()函数得到的一系列样例数值。

ndarray的常用属性

  • ndim:返回ndarray的维数,比如arr.ndim
  • itemsize:返回ndarray中存的元素的字节长度
  • shape:获取ndarray每一维的大小
  • size:返回ndarray中的元素个数
  • flat:使用一个值覆盖原ndarray数组中所有元素

这些函数用法如下:

>>> arr=np.array([[1,2,3],[4,5,6]],dtype=np.int64)
>>> print(arr)
[[1 2 3]
 [4 5 6]]
>>> print(arr.itemsize)
8
>>> print(arr.shape)
(2, 3)
>>> print(arr.size)
6
>>> arr.flat=100
>>> print(arr)
[[100 100 100]
 [100 100 100]]

itemsize返回了arr中每个元素占的字节数,我们的数据是int64,即一个int占64位(bit),也就是8字节;arr是两行三列,所以shape返回的是(2,3);size是所有元素的个数,两行三列一共有2x3=6个元素;最后让arr.flat=100,即用100覆盖arr中每个元素。

ndarray变形

在数组的操作中,我们经常用到数组的resize,比如说将shape=(2,12)(2行12列)的数组转化成shape=(4,6)(4行6列)的数组。实现resize主要有两种方法:
方法一:改变数组的shape属性
例子:

>>> arr=np.arange(24)
>>> arr
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])
>>> arr.shape=(4,6)
>>> arr
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]])

注意,在resize前后,arr数组的元素数量必须一样。在以上例子中就是24=4x6。需要注意的是,这种方法会改变原数组。
方法二:使用reshape函数
我们同样可以使用ndarray对象的reshape函数对数组进行变形:

>>> arr=np.arange(24)
>>> arr
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])
>>> newArr=arr.reshape(2,12)
>>> newArr
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]])
>>> arr
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]])

可以看到,reshape函数不会改变原数组的形状,而是返回了一个新的ndarray对象。
方法三:flatten函数
这函数专门把多维数组拉平,转换成一维数组并返回,原数组不变。

>>> arr=np.arange(12)
>>> arr
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> arr.shape=(3,4)
>>> arr
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> newArr=arr.flatten()
>>> newArr
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> arr
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

可以看到,将数组拉平后返回的是新数组,并没有改变原数组。

ndarray的访问

一维数组的访问

可以通过索引或者切片进行访问和修改一维数组,提取任意行元素、列元素以及单元格元素等。
例子:

>>> x=np.array([1,2,3,4,5,6])
>>> ele=x[0]
>>> ele
1
>>> newx=x[0:3:2]
>>> newx
array([1, 3])

对于索引访问没什么需要注意的地方,只要索引不要非法越界就行;切片方法要注意的是,对于[start : end : step]这样的切片方法,start和end是左开右闭,即可以取到start索引的位置,不能取到end索引所在位置的元素,最多取到end-1索引所在位置的元素。

多维数组的访问和变换

索引和切片

和一维数组一样,多维数组同样可以用索引和切片进行访问。使用索引的时候有两种方式:

>>> arr=np.arange(24)
>>> arr.shape=(2,3,4)
>>> arr
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]]])
>>> arr[0][0][0]
0
>>> arr[0,0,0]
0

第一种和list还有c语言数组用法是一样的;第二种是numpy数组特有的访问方式,即在每个维度上选择一个索引,所有维度的索引结合之后就是我们想要的位置的值。这样就引出了另一个方法:针对不同维度切片。

>>> x=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
>>> x
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
>>> x[:2,2]
array([3, 7])
>>> x[:2,:]
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

x[:2,2]表示了第一维度取索引为0和1(:2其实是0:2的缩写),第二维度取索引为2,综合起来就是两个元素:x[0,2]和x[1,2],返回是一个新的数组,即[3,7]。

同时,我们可以使用:符号省略维度信息,表示取这个维度中所有索引,比如说例子中的x[:2,:],表示在第一个维度上取索引为0和1,第二个维度上取索引为0,1,2,3,即所有索引。最终得到的结果是:x[0,0],x[0,1],x[0,2],x[0,3],x[1,0],x[1,1],x[1,2],x[1,3]八个元素。

在多维切片中,经常使用省略号…提取多维数组的某些完整行、列元素,省略号表示剩余的维度全是取所有索引。例子:

>>> arr.shape=(2,2,3)
>>> arr
array([[[ 0,  1,  2],
        [ 3,  4,  5]],

       [[ 6,  7,  8],
        [ 9, 10, 11]]])
>>> arr[0,...]
array([[0, 1, 2],
       [3, 4, 5]])

在以上的例子中,arr[0,...]其实和arr[0,:,:]是等价的,在第一维度取索引0,第二第三维度取全部索引。
我们还可以在不同维度中使用列表,列表中保存的是我们将要提取这一维度的所有索引下标。

>>> arr=np.arange(12)
>>> arr
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> arr.shape=(3,4)
>>> arr
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> arr[[1,1,2],[0,2,3]]
array([ 4,  6, 11])
>>> arr[2,[0,2,3]]
array([ 8, 10, 11])

arr[[1,1,2],[0,2,3]]表示的是提取数组中(1,0),(1,2),(2,3)三个位置的元素;arr[2,[0,2,3]]表示第一维度索引为2,第二维度索引分别为0,2,3的元素集合,即提取了(2,0),(2,2),(2,3)三个位置的元素。

按照条件筛选

我们同时可以在[]中写入条件,从而筛选出我们需要的数据,例如:

>>> arr
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> arr[arr>5] # 运算符可以是>,>=,==等
array([ 6,  7,  8,  9, 10, 11])
>>> Judge=lambda x:x>9
>>> arr[Judge(arr)]
array([10, 11])

这个方法返回的是一维数组。会对数组中每一个元素进行遍历,判断是否满足条件,如果这个元素满足条件,那么就放入一维数组中,最终返回这个一维数组。有意思的是,这个方法会自动将数组中每个元素拿出来进行筛选,所以尽管我们写的是Judge(arr)实际上是对arr中每个元素输入Judge函数,将这些元素中返回为True的元素放入一维数组。

unique函数筛选出数组中非重复的元素

我们可以通过numpy提供的函数获取一个adarray中所有不重复元素,返回的同样是个一维数组。

>>> arr=np.array([[1,1,2,3],[2,5,1,10]])
>>> arr
array([[ 1,  1,  2,  3],
       [ 2,  5,  1, 10]])
>>> np.unique(x)
array([ 1,  2,  3,  4,  5,  6,  7,  8, 11, 22, 33, 44])

clip函数对元素进行修剪

我们可以使用ndarray对象提供的clip方法,将所有比给定最大值还大的元素全部设置成给定值的最大值,比给定最小值还小的元素全部设置成给定的最小值。例:

>>> arr
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> arr.clip(3,8)
array([[3, 3, 3, 3],
       [4, 5, 6, 7],
       [8, 8, 8, 8]])

可以看到,数组中小于3的元素都变为3,大于8的元素都变成8。

numpy用于科学计算的函数

numpy提供了很多用于科学计算的函数,这些函数用于统计、线性代数、和矩阵运算。

  • sum(arr[,axis]):计算arr数组中的和,其中axis可选,在指定为维度上进行sum操作,否则是对整个数组的值求和。
  • mean(arr[,axis]):计算arr数组中的均值,axis可选参数,在指定维度上求均值。
  • average(arr[,axis,weights]):计算arr数组的平均值,axis是可选参数,在指定维度上求均值,weight是可选参数,代表权值矩阵,用于求arr的加权平均值。注意:当维度axis没有被指定的时候,权重矩阵的shape一定要和arr的shape一致才可以。当指定了axis,权重矩阵的length一定要和指定的axis的length相同。
  • var(arr[,axis]):计算arr数组的方差,axis可选参数,在指定维度上求方差。
  • std(arr[,axis]):计算arr数组的标准差,axis可选参数,在指定维度上求标准差。(标准差为方差的平方根)
  • median(arr[,axis]):计算arr数组的中位数,axis可选参数,在指定维度上求中位数。(中位数为所有元素从小到大排序后,中间那个数字,如果有偶数个元素,那么是中间两个元素的均值)
  • max(arr[,axis]):计算arr中的最大值,axis可选参数,在指定维度上求最大值。
  • min(arr[,axis]):计算arr中的最小值,axis可选参数,在指定维度上求最小值。
  • ptp(arr[,axis]):计算arr中的极差,axis可选参数,在指定维度上求极差。极差=最大值-最小值。
  • argmax(arr[,axis]):返回arr中最大元素的索引,axis可选参数,在指定维度上求最大元素所在的索引。
  • argmin(arr[,axis]):返回arr中最小元素的索引,axis可选参数,在指定维度上求最小元素所在的索引。
  • prod(arr[,axis]):计算arr中所有元素的累计乘。axis可选参数,在指定维度上计算所有元素的累计乘。
  • T:返回这个矩阵的转置矩阵,注意,这是ndarray的一个属性,并不是函数。
  • transpose(arr):返回这个矩阵的转置矩阵
  • I:返回这个矩阵的逆矩阵
  • np.cov(x,y):返回x和y的协方差矩阵。这个函数可以只有一个参数x,表示的是求两个x的协方差矩阵。
  • np.corrcoef(x,y):计算x和y相关系数。同样,这个函数也可以只有一个参数x,表示的是求两个x矩阵的相关系数。

小Tips:以上提到的这些函数中,有些函数存在两种使用方式:1、直接在ndarray对象中调用这些函数;2、将ndarray对象作为参数传入np.xxx()中。可能这样讲有点不太清楚,通过看一个例子就清楚了:

>>> arr
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> arr.transpose()
array([[ 0,  4,  8],
       [ 1,  5,  9],
       [ 2,  6, 10],
       [ 3,  7, 11]])
>>> np.transpose(arr)
array([[ 0,  4,  8],
       [ 1,  5,  9],
       [ 2,  6, 10],
       [ 3,  7, 11]])
>>> arr.mean(axis=1)
array([1.5, 5.5, 9.5])
>>> np.mean(arr,axis=1)
array([1.5, 5.5, 9.5])

对于transpose()函数,两种方法都可以得到原矩阵的转置矩阵;对于mean()函数,除了使用方法不同,结果是一样的,axis参数的含义也是一样的。所以在使用的时候,两种方式都可以。

部分函数使用举例:

>>> arr=np.arange(12)
>>> arr=arr+1 # 利用广播机制,对所有元素+1
>>> arr
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])
>>> arr.max() # 最大值
12
>>> arr.min() # 最小值
1
>>> arr.mean() # 均值
6.5
>>> arr.var() # 方差
11.916666666666666
>>> arr.std() # 标准差
3.452052529534663
>>> arr.prod() # 各元素乘积
479001600
>>> np.median(arr) # 中位数
6.5
>>> arr.ptp() #极差
11
>>> arr.sum() # 各元素之和
78
>>> arr.argmax() #值最大的那个元素的索引
11
>>> arr.argmin() #值最小的那个元素的索引
0
>>> arr.shape=(3,4) # 将矩阵reshape成3行4列
>>> arr
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
>>> arr.T # 转置矩阵
array([[ 1,  5,  9],
       [ 2,  6, 10],
       [ 3,  7, 11],
       [ 4,  8, 12]])
>>> arr=np.mat(arr) # 将ndarray转化成矩阵matrix,这样才能使用I得到逆矩阵
>>> arr
matrix([[ 1,  2,  3,  4],
        [ 5,  6,  7,  8],
        [ 9, 10, 11, 12]])
>>> arr.I # 逆矩阵
matrix([[-0.375     , -0.1       ,  0.175     ],
        [-0.14583333, -0.03333333,  0.07916667],
        [ 0.08333333,  0.03333333, -0.01666667],
        [ 0.3125    ,  0.1       , -0.1125    ]])

本篇太长了,非常影响观看体验,下一节接着更 : )
下节链接:

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值