学习自:NumPy 教程 | 菜鸟教程

官网:Numpy官方文档

1、简介

numpy主要用于数组计算,包含:

1)一个强大的N维数组对象ndarray

2)广播功能函数

3)整合 C/C++/Fortran代码的工具

4)线性代数、傅里叶变换、随机数生成等功能

numpy通常与scipy(scientific Python)和matplotlib(绘图库)一起使用,这种组合广泛用于替代MatLab,是一个强大的科学计算环境,有助于我们通过Python学习数据科学或者机器学习。

scipy是一个开源的Python算法库和数学工具包。

scipy中包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解、....

matplotlib是Python编程语言及numpy库的可视化操作界面。它为通用的图形用户界面(GUI)提供了应用程序接口(API),常用的GUI工具包有Tkinter,wxPython,Qt、GTK+。

2、Ndarray对象

numpy最重要的特点是Ndarray对象,Ndarray对象即N维数组对象,它是一系列同类型数据的集合,以0为下标开始进行集合中元素的索引。

特性

1)元素为同类型

2)每个元素在内存中占用空间相同

创建一个ndarray只需要调用numpy.array()即可

numpy.array(
object,
dtype=None,
copy=True,
order=None,
subok=False,
ndmin=0
)

参数

参数 说明
object 数组或嵌套的List
dtype 数组元素的数据类型
copy 对象是否需要复制
order 创建数组的方向,C为行方向,F为列方向,A为任意方向(默认)
subok 默认返回一个与基类类型一致的数组
ndmin 指定生成数组的最小维度

创建时指定dtype和ndmin,可以补充更多细节,举例如下:

nd = np.array(
[1,2,3],
ndmin=2 #最小维度为2
) [[1 2 3]] nd = np.array(
[1,2,3],
dtype=complex #指定类型为负数
) [1.+0.j 2.+0.j 3.+0.j]

补充

1)二维数组生成时,各行间以逗号,隔开,每个list代表一行

2)n维数组就是n个[]的嵌套

3)生成类似

[("raju",21),("anil",25),("ravi", 17), ("amar",27)]

的数组时,dtype需要为每个字段指定名称和类型,方式为:

dt = np.dtype( [ (name1 , dtype) , (name2 , dtype) , ... ] )

而上述数组的生成则为

dt = np.dtype([('name',  'S10'),('age',  int)])
a = np.array([("raju",21),("anil",25),("ravi", 17), ("amar",27)], dtype = dt)

2.1、属性

ndarray.属性名

属性 说明
ndim 维数
shape 尺寸,返回(n,m)说明是n行m列
size 元素个数,等于n*m
dtype 元素类型
itemsize 每个元素大小,以字节B为单位
flags 内存
real 元素实部
imag 元素虚部

numpy提供了reshape()函数来调整数组的大小

用法

a = np.array([[1,2,3],[4,5,6]])
b = a.reshape(3,2) #把数组a素重新组合为3行2列的新数组
print (b)
[[1 2]
[3 4]
[5 6]]

reshape返回原数组的变形后的副本,因此对新数组b中元素值的改写,会导致a中对应值的变化

3、创建数组

3.1、array

见上文

3.2、直接创建

除了用array方法构造一个数组外,也可以通过以下几种方式创建:

3.2.1、empty

说明

empty方法创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组

用法

numpy.empty(
shape,
dtype=float,
order='C'
)

参数

参数 说明
shape 形状;形式为[n,m]或(n,m),n行m列
dtype 类型
order 顺序;'C'或'F'分别表示行优先和列优先

3.2.2、zeros

说明

创建指定大小的数组,元素填充0

用法

numpy.zeros(
shape,
dtype=float,
order='C'
)

参数同empty

3.2.3、ones

说明

创建指定大小的数组,元素填充1

用法

numpy.ones(
shape,
dtype=None,
order='C'
)

3.3、利用random库生成随机数组——np.random模块

学习自:numpy的random模块详细解析 - 左手十字 - 博客园

Random sampling (numpy.random) — NumPy v1.21 Manual

函数 说明
rand(x,y,z) 生成0-1间的随机值矩阵,尺寸为x*y*z
randn(x,y,z) [-1,1]标准正态分布矩阵,尺寸为x*y*z
randint(low,high,size) [low,high)区间内尺寸为size的随机整数,size=(3,3)表示3*3的矩阵
random(size) 返回在区间[0,1)内的浮点数,尺寸为size

以上生成随机数的方法,有可能出现重复的情况,如果要避免这种情况,可以用random.sample( a , n )(注意,这里是random模块而非np.random)

random.sample( a,n )可以在一个序列a中不重复地采样n个值。

3.4、从已有的数组创建数组

3.4.1、asarray

说明

生成list、tuple等元素组的数组形式

用法

numpy.asarray(
a,
dtype = None,
order = None
)

参数

a:任意形式的输入参数,可以是:list、tuple,互相嵌套的list和tuple、多维数组

例子

a=numpy.asarray([(1,2,3),(4,5)])
a
array([(1, 2, 3), (4, 5)], dtype=object)

3.4.2、fromiter

说明

从可迭代对象中建立ndarray对象,返回一维数组

用法

numpy.fromiter(
iterable,
dtype,
count=-1
)

参数

参数 说明
iterable 可迭代对象
dtype 返回数组的数据类型,必需
count 读取的数量,默认-1即全部

例子

list=range(5)

x=numpy.fromiter(list, dtype=float)
x
array([0., 1., 2., 3., 4.]) x=numpy.fromiter(list, dtype=float,count=3) #只读取3个
x
array([0., 1., 2.])

3.5、从数值范围创建数组:arange、linspace、logspace

3.5.1、arange

说明

根据范围和步长,返回一个一位数组

用法

numpy.arange(
start = 0,
stop,
step = 1,
dtype = None
)

参数

参数 说明
start 起始值,默认0
stop 终止值(不包含)
step 步长,默认1
dtype 类型,默认使用输入数据的类型

例子

x=np.arange(5) #0到4
x
array([0, 1, 2, 3, 4]) x=np.arange(10,20)#10到19
x
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])

3.5.2、linspace

说明

根据范围和数组中元素数量,返回一个等差数列一维数组

区别于arange:arange是给出了步长,元素数量由步长决定;linspace是给出了数量,步长由数量决定

用法

numpy.linspace(
start,
stop,
num=50,
retstep=False,
dtype=None
)

参数

参数 说明
start 起始值
stop 终止值(包含)
num 元素数量
retstep 如果为True,则生成的数组中会显示间距,反之不会
dtype 类型

例子

只看retstep的效果

x=np.linspace(10,20,11,retstep=True)
x
(array([10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20.]), 1.0)

3.5.3、logspace

说明

创建一个指定元素个数等比数列一位数组

用法

np.logspace(
start,
stop,
num=50,
endpoint=True,
base=10.0,
dtype=None
)

参数

参数 说明
start 序列的起始值为:base**start(即base^start)
stop 序列的终止值为:base**stop(包含)
num 元素数量
base 底数,用于生成起始值和终止值
dtype 类型

补充

当start-stop+1 == num时,会生成从base**start 到 base**stop的等比数列,比值为base,数量为num

例子

生成1,2,4,8,...,512

#1=2**0 512=2**9 所以start=0,end=9,num=9-0+1=10
x=np.logspace(0,9,10,base=2)
x
array([ 1., 2., 4., 8., 16., 32., 64., 128., 256., 512.])

4、切片与索引

4.1、切片

4.1.1、一维数组

通过 [start:stop:step]来进行切片操作,stop不包含其中

a=np.arange(10)
b=a[2:7:2]
b
array([2, 4, 6])

另外,还有其他几种写法

[start :] 从start到最后(步长为1)
[: stop] 从开始到stop(不包含)
[start : : step]与[: stop : step] 前两种的延伸,指定步长

4.1.2、二维数组

[r_start:r_stop , c_start:c_stop]

写法与一维数组相同,不过格式要多一个维度

例子

a=np.arange(20)
c=a.reshape(5,4) array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19]])
#c是5行4列的数组

#下面提取2、3行,1、2列的元素
c[1:3,0:2]
array([[4, 5],
[8, 9]])

4.1.3、用省略号...全选某一列/行

在处理多维数组时,如果某若干行/列的元素时,可以用以下两种方式

#提取第3列
c[:,2]
array([ 2, 6, 10, 14, 18])
c[...,2]
array([ 2, 6, 10, 14, 18]) #提取第3行
c[2,:]
array([ 8, 9, 10, 11])
c[2,...]
array([ 8, 9, 10, 11])

个人还是更习惯用冒号:

4.2、高级索引

4.2.1、数组形式的索引

用法(以二维数组为例):

#x为一二维数组
x[ [x1,x2] , [y1,y2] ]

上述索引的结果为一个一维数组[ x[x1,y1] , x[x2,y2] ],行索引与列索引中的元素一一对应,两两组合得到实际的索引。

4.2.2、布尔索引(很有用)

说明:筛选获得符合指定条件的数组元素

要求:索引必须返回布尔值(True或False)

用法:

x[ x > 5 ] 筛选x中大于5的元素
x[ func (x) ] 筛选x中符合函数func的元素,要求func必须返回True或False

例子:

#逻辑运算
a=np.array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19]])
a[a > 5]
array([ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) #函数
b = np.array([1, 2+6j, 5, 3.5+5j])
b[np.iscomplex(b)]
array([2. +6.j, 3.5+5.j])

如果想看数组元素对于布尔运算的实际响应,可以直接用 索引

a > 5
array([[False, False, False, False],
[False, False, True, True],
[ True, True, True, True],
[ True, True, True, True],
[ True, True, True, True]]) np.iscomplex(b)
array([False, True, False, True])

4.2.3、花式索引

说明:以任意顺序取整行和整列构成新数组

区别于整数数组索引:

整数数组索引总是同时给出相同尺寸的行list和列list,从而获取某个具体元素的下标(下标获取方式为,同一个位置的行对应同一个位置的列,对应关系为一对一;假设list尺寸为n,则最终提取n个元素);

花式索引:

给出一个list时,标识具体的行,提取整行元素作为一个新的数组;

给出两个list时(需要用到np.ix_方法),行下标list与列下标list的对应关系为一对多,每个行下标都会与每个列下标互相组合,此时行list与列list尺寸可以不同,假设行列list尺寸分别为m与n,那么最终提取m*n个元素,即m行n列

例子:

①传入一个list

a=np.arange(20)
c=a.reshape(5,4)#c为5*4的数组


#第3行
c[2]
array([ 8, 9, 10, 11]) #第4、1、2、3行
c[ [3,0,1,2] ]
array([[12, 13, 14, 15],
[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])

②传入两个list

c[ np.ix_( [3,0,1,2] , [2,0,1] ) ]
#行组织方式为原数组的3、0、1、2行
#列组织方式为原数组的对应行2、0、1列
#综合起来就是
#3行2列 3行0列 3行1列
#0行2列 0行0列 0行1列
#...
array([[14, 12, 13],
[ 2, 0, 1],
[ 6, 4, 5],
[10, 8, 9]])

5、数组操作

分类:修改数组形状、转置、连接、分割、去除重复

之所以这一节的标题用数组操作而不是方法,是因为有些操作是方法,有些是属性

5.1、修改数组形状

reshape 不改变数据的条件下修改形状
flatten 返回展开数组的拷贝,对拷贝的修改不会影响原始数组
ravel 返回展开数组,修改会影响原始数组
flat(属性) 数组元素迭代器
meshgrid 1D数组网格化为2D网格

5.1.1、reshape

用法:

nd.reshape(m,n)

说明:将a重构为m*n大小,返回重构后的数组,前提是m*n == a.size()

5.1.2、flatten

用法:

nd.flatten(order = 'C')

参数:

order:展开方式,'C'——按行、'F'——按列

说明:按参数order说明的方式将数组展开,返回展开数组的拷贝,对拷贝的修改不影响原始数组

5.1.3、ravel

用法:

nd.ravel(order = 'C')

参数和说明都与flatten相同,不同之处在于没有拷贝,修改会影响原始数组

5.1.4、flat(属性)

nd.flat

说明:返回一个iterable,可以用for循环迭代访问全部数组元素

迭代访问数组元素的方法:

#1. a.flat
for element in a.flat :
print(element)
#2. a.ravel()和a.flatten()
for element in a.ravel():
  print(element)
for element in a.flatten():
  print(element)
#3. a.shape
for i in range(a.shape[0]):
for j in range(a.shape[1]):
print(a[i,j])
#如果直接对数组迭代,返回的只是各行,可通过对这些行二次迭代实现访问所有元素的目的
#4.
for row in a:
  for element in row:
    print(element)

推荐使用1、3、4种,当然一维数组直接用一个for循环就可以了

5.1.5、meshgrid

说明

由低维数组生成高维网格,主要用于生成坐标系的各个轴坐标(区域插值、等高线绘制常用)。

如果参数中有n个xi,那么最终生成的就是n维网格。

不过我们最常用的是两个xi,即x和y,这样生成的就是二维坐标系的横纵坐标。

这些xi都是1D array,尺寸可以不同,最终生成的坐标系大小就是len(x1)*len(x2)*len(x3)*...

用法

np.meshgrid(x1,x2,...,xn, copy=True, sparse=False, indexing='xy')

参数

参数

类型

默认值

说明

x1,x2,...,xn 1D array   用于构建坐标网格的各个轴,最终的坐标系大小就是这些轴的乘积
indexing {'xy','ij'} 'xy'

输出的坐标系

'xy':笛卡尔坐标系

''ij':矩阵坐标系

sparse bool False 是否返回稀疏矩阵以节约内存
copy bool True

如果是True,会新生成结果array;

False,则是在原array上生成,以节约内存。

返回值

与输入的x1、x2、...、xn个数相等的X1、X2、...、Xn,它们都是n维数组。

假设x1~xn的大小为Ni=len(xi),那么,根据参数indexing的取值,X1~Xn有不同的取值:

  • 'ij':X1~Xn为(N1,N2,N3,...,Nn)尺寸的array
  • 'xy':X1~Xn为(N2,N1,N3,...,Nn)尺寸的array

有n个xi,结果就要用n个Xi承接:

X1,X2,...,XN = np.meshgrid(x1,x2,...,xn)

例子

import numpy as np
nx,ny=(3,2)
x=np.linspace(0,1,nx)#(0,1)间生成3个点
y=np.linspace(0,1,ny)#(0,1)间生成2个点 xv,yv=np.meshgrid(x,y)
print(xv,yv)
[[0. 0.5 1. ]
[0. 0.5 1. ]] [[0. 0. 0.]
[1. 1. 1.]] xv, yv = np.meshgrid(x, y, sparse=True)#稀疏矩阵
print(xv,yv)
[[0. 0.5 1. ]] [[0.]
[1.]]

②坐标系绘图

import matplotlib.pyplot as plt
x = np.arange(-5, 5, 0.1)
y = np.arange(-5, 5, 0.1)
xx, yy = np.meshgrid(x, y, sparse=True)
z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
h = plt.contourf(x, y, z) #等值区域图
plt.axis('scaled')
plt.show()

5.2、转置

两种实现途径:numpy.transpose()、ndarray.T

a.T
array([[1, 2],
[2, 3],
[3, 4]]) np.transpose(a)
array([[1, 2],
[2, 3],
[3, 4]])

5.3、连接数组:concatenate

用法:

np.concatenate((a1,a2,...),axis=0)

参数:

a1,a2,...:相同类型的数组

axis:连接数组的方向(默认0,即行方向)

说明:axis为0,将a2按行的方式成为a1的新行加入到a1中;axis为1,按列加入

a=np.arange(1,5).reshape(2,2)
b=np.arange(5,9).reshape(2,2) np.concatenate((a,b)) #行拼接
array([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
np.concatenate((a,b),1) #列拼接
array([[1, 2, 5, 6],
[3, 4, 7, 8]])

5.4、分割数组:np.split

用法:

np.split(
arr,
indices_or_sections,
axis
)

参数:

arr:被分割的数组

indices_or_sections:如果是一个整数n,则平均切分为n份;如果为list,则切点位置为list中的数字(切点元素归下一个数组,即1号切点元素在第2个数组中,2号切点在第3个数组中)

axis:切割方向;默认0,对行切割,新数组列数同原数组;axis=1,对列切割,新数组行数同原数组

5.5、去除重复元素:unique

说明:去除数组中的重复元素,返回一个全是不同元素的一位数组

用法:

np.unique(
arr,
return_index,
return_inverse,
return_counts
)

参数:

arr:输入数组,如果不是一位数组则会展开

return_index:如果为True,返回去重数组中的元素在旧list中的下标,以一维数组形式存储

return_inverse:如果为True,返回去重数组中的元素在新list中的下标,以一维数组形式存储

return_counts:如果为True,返回去重数组中的元素在原数组中的出现次数,以一维数组形式存储

例子:

u,index,indice,c=np.unique(a,return_index=True,return_inverse=True,return_counts=True)

u #去重数组
array([2, 5, 6, 7, 8, 9])
index #元素在旧数组中的下标
array([1, 0, 2, 5, 8, 4], dtype=int64)
indice #元素在新数组中的下标
array([1, 0, 2, 0, 5, 3, 1, 2, 4, 0], dtype=int64)
c #各元素出现次数
array([3, 2, 2, 1, 1, 1], dtype=int64)

6、取整

取整操作返回取整后的数组,对原数组没有影响

6.1、四舍五入:np.around

说明:对整个数组的所有元素进行四舍五入

用法:

np.around(a , decimals=0)

参数:

a:数字数组

decimals:保留到哪一小数位。默认为0,即个位;1表示小数点后1位,-1表示十位,-2表示百位

6.2、向下取整:np.floor

说明:数值上小于或等于原数的最大整数,而非绝对值

用法:np.floor(a)

6.3、向上取整:np.ceil

说明:数值上大于或等于原数的最小整数

用法:np.ceil(a)

7、算数函数

7.1、倒数:np.reciprocal()

说明:返回逐元素取倒数后的新数组

用法:np.reciprocal(a)

8、统计函数

8.1、最大、最小值:np.amin()与np.amax()

用法:

二者用法相同,以amax说明

np.amax(a ,axis = None)

参数:

a:数组

axis:方向;默认None是全数组,0是列方向——给出每列最大值的array,1是行方向——给出包含每行最大值的array

8.1.5、最大最小值的索引:np.argmax()与np.argmin()

用法:

np.argmax(a ,axis = None)

参数同上

说明:argmax返回amax选出的最大值在原数组中的索引;即形式与amax相同,但数值是这些数的索引

8.2、最大最小元素之差:np.ptp()

用法:

np.ptp(a , axis = None)

参数:

a:数组

axis:方向,默认None是全数组,0是列方向——给出每列最大值的array,1是行方向——给出包含每行最大值的array

8.3、中位数:np.median()

用法:

np.median(a , axis = None)

参数同上

8.4、算数平均值:np.mean()

用法:

np.mean(a , axis = None)

参数同上

8.5、加权平均值:np.average()

说明:该函数根据在另一个数组中给出各自的权重计算给定数组中各元素的加权平均值

用法:

np.average(
arr,
axis=None,
weights,
returned=False
)

参数:

arr:原数组

axis:方向,同上

weights:权重数组;如果axis=None,那么尺寸与arr相同,是对每个元素的加权;如果axis=0,尺寸等于行数,是每列元素的加权平均值;如果axis=1,尺寸等于列数,是每行元素的加权

returned:如果为True,则额外返回权重的和

8.6、标准差:np.std()

用法:

np.std(a , axis=None)

8.7、方差:np.var()

用法:

np.var(a , axis=None)

9、排序、按条件筛选元素

9.1、排序

9.1.1、元素排序:np.sort()

用法:

numpy.sort(
a,
axis = -1,
kind = 'quicksort',
order = None
)

参数:

a:待排序数组

axis:方向;axis = 0 ,按列进行排序;axis = 1,按行进行排序。默认为-1,即最大的axis,二维情况下为1,三维情况下为2

kind:排序算法,默认为快速排序

order:如果数组包含字段,则该参数指定参与排序的字段

例子:

#axis
a = np.array([[3,7],[9,1]])
np.sort(a) #行排序
array([[3, 7],
[1, 9]]) np.sort(a,axis=0) #列排序
array([[3, 1],
[9, 7]]) #order
dt = np.dtype([('name', 'S10'),('age', int)])
a = np.array([("raju",21),("anil",25),("ravi", 17), ("amar",27)], dtype = dt)
#按name排序
np.sort(a, order = 'name')
[(b'amar', 27) (b'anil', 25) (b'raju', 21) (b'ravi', 17)]

9.1.2、排序后的索引值:np.argsort()

用法:

np.argsort(
a,
axis = -1,
kind = 'quicksort',
order = None
)

说明:返回对数组a进行np.sort排序后,排序结果在原数组中的索引下标

9.2、筛选

其实在4.2布尔索引已经讲了如何筛选数组中符合条件的元素,这里给出获取筛选元素的索引的方法:np.where()

np.where ( x > 5 ) #数组x中,大于5的元素的索引
np.where ( func(x) )#数组x中,使func返回True的元素的索引

返回值为索引,存储形式为,4.1节整数数组索引。比如一个二维数组,返回值就为x索引数组与y索引数组的组合

例子:

x=np.arange(9).reshape(3,3)
np.where( x > 3 )
(array([1, 1, 2, 2, 2], dtype=int64), array([1, 2, 0, 1, 2], dtype=int64))

第一个为x索引,第二个为y索引,二者一一对应得到实际二维索引。

可直接用该索引提取数组元素:

y = np.where( x > 3 )
x[y]
array([4, 5, 6, 7, 8]) #这等价于 x[ x > 3 ]

所以要提取元素的话,直接用布尔索引即可,而要提取元素索引的话,就要用到np.where了

最新文章

  1. 【学】React的学习之旅3 - 添加事件(onClick)
  2. org.hibernate.NonUniqueObjectException: a different object with the same identifier value was alread---------程序报错
  3. FIDO 标准简介
  4. Redis系列(一)——简介及安装
  5. c++实现gray code(格雷码)
  6. EasyMock的原理及使用方法
  7. Home-brew 安装&卸载 Git
  8. 进程关系之tcgetpgrp、tcsetpgrp和tcgetsid函数
  9. 去除后台ckeditor的style="...."的样式
  10. 怎么调试EXC_BAD_ACCESS错误
  11. Angular学习笔记(2)——TODO小应用
  12. nl2br()与nl2p()函数,php在字符串中的新行(\n)之前插入换行符
  13. C++函数后面的throw()
  14. 干货!手把手教你如何使用第三方通讯服务实现LayIM Socket组件开发。
  15. python之爬虫
  16. DRBD的主备安装配置
  17. ScrollView的阻尼回弹效果实现(仿qq空间)
  18. Swap Nodes in Pairs(交换节点)
  19. [C程序设计基础]一些常用的系统函数
  20. nginx 中 ulimit 使用修改文件句柄数

热门文章

  1. vivo数据库与存储平台的建设和探索
  2. python_f-string格式化字符串文字
  3. django之分页算法实现(Paginator)
  4. HTML Entry 源码分析
  5. js 每日一更(数组转换成前端更容易解析的树状结构)
  6. debian下编译安装redis并加入到systemd启动管理
  7. Entity Framework 在OrderBy排序中使用字符串
  8. Java 变量的声明及初始化
  9. 为什么后台给前台Date是时间戳,而前台给后台则直接是时间字符串?
  10. Centos 系统目录概述