Numpy
NumPy是一个开源的Python科学计算基础库
- 一个强大的N维数组对象 ndarray
- 广播功能函数
- 整合C/C++/Fortran代码的工具
- 线性代数、傅里叶变换、随机数生成等功能
Numpy是Scipy、Pandas等数据处理或科学计算库的基础
numpy 的引用:
import numpy as np
N维数组对象:ndarray
- 数组对象可以去掉元素间运算所需的循环,使以为向量更像单个数据
- 设置专门的数组对象,经过优化,可以提升这类应用的运算速度
科学计算中每一个维度所有数据的类型往往相同
- 数组对象采用相同的数据类型,有助于节省运算和存储空间
ndarray是一个多维数组对象,由两部分构成:
- 实际的数据
- 描述这些数据的元数据(数据维度、数据类型等)
ndarray数组一般要求所有元素类型相同(同质),数组下标从0 开始
>>> import numpy as np
>>> a = np.array([[0, 1, 2, 3, 4],[9, 8, 7, 6, 5]]) #np.array()生成一个ndarray数组
>>> a
array([[0, 1, 2, 3, 4],
[9, 8, 7, 6, 5]])
>>> print(a)
[[0 1 2 3 4]
[9 8 7 6 5]] #np.array()输出成[]形式,元素由空格分割
ndarray对象的属性
属性 | 说明 |
---|---|
.nidim | 秩,即轴的数量或维度的数量 |
.shape | ndarray对象的尺度,对于矩阵,n行m列 |
.size | ndarray对象元素的个数,相当于.shape中n*m的值 |
.dtype | ndarray对象的元素类型 |
.itemsize | ndarray对象中每个元素的大小,以字节为单位 |
>>> a = np.array([[0, 1, 2, 3, 4],[9, 8, 7, 6, 5]])
>>> a.ndim
2
>>> a.shape
(2, 5)
>>> a.size
10
>>> a.dtype
dtype('int32')
>>> a.itemsize
4
ndarray数组的创建方法
- 从Python中的列表、元素等类型创建ndarray数组
- 使用NumPy中函数创建ndarray数组,如:arange,ones,zeros等
- 从字节流(raw bytes)中创建ndarray数组
- 从文件中读取特定格式,创建ndarray数组
(1) 从Python中的列表、元素等类型创建ndarray数组
x = np.array(list/tuple, dtype = ?)
(2)使用NumPy中函数创建ndarray数组,如:arange,ones,zeros等
函数 | 说明 |
---|---|
np.arange(n) | 类似range()函数,返回ndarray乐行,元素从0到n-1 |
np.ones(shape) | 根据shape生成一个全1数组,shape是元祖类型 |
np.zeros(shape) | 根据shape生成一个全0数组,shape是元祖类型 |
np.full(shape,val) | 根据shape生成一个数组,元素值都是val |
np.eye(n) | 创建一个正方的n*n单位矩阵,对角线为1,其余为0 |
np.ones_like(a) | 根据数组a的形状生成一个全1数组 |
np.zeros_like(a) | 根据数组a的形状生成一个全0数组 |
np.full_like(a,val) | 根据数组a的形状生成一个数组,每个元素值都是val |
np.linspace() | 根据起止数据等间距地填充数据,形成数组 |
np.concatenate() | 将两个或多个数组合并成一个新的数组 |
>>> a = np.linspace(1, 10, 4) #(起始值,最后的值,个数)
>>> a
array([ 1., 4., 7., 10.])
>>> b = np.linspace(1, 10 ,4, endpoint = False) #endpoint:是否包含最后一个数
>>> b
array([1. , 3.25, 5.5 , 7.75])
>>> c = np.concatenate((a,b))
>>> c
array([ 1. , 4. , 7. , 10. , 1. , 3.25, 5.5 , 7.75])
ndarray数组的变换:对于创建后的ndarray数组,可以对其进行维度变换和元素类型变换
ndarray维度变换
方法 | 说明 |
---|---|
.reshape(shape) | 不改变数组元素,返回一个shape形状的数组,原数组不变 |
.resize(shape) | 与.reshape()功能一致,但修改原数组 |
.swapaxes(ax1, ax2) | 将数组n个维度中两个维度进行调换 |
.flatten() | 对数组进行降维,返回折叠后的一维数组,原数组不变 |
>>> a = np.ones((2, 3, 4),dtype = np.int)
>>> a.reshape((3, 8))
array([[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1]])
>>> a
array([[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]]])
>>> a.flatten()
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1])
ndarray数组的类型变换
new_a = a.astype(new_type)
>>> a.astype(np.float)
array([[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]],
[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]])
ndarray数组向列表的转换
ls = a.tolist()
>>> a.tolist()
[[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]], [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]]
ndarray数组的操作
数组的索引和切片
索引:获取数组中特定位置元素的过程
切片:获取数组元素自己的过程
一维数组的索引和切片:与Python的列表类似
>>> a = np.array([9, 8, 7, 6, 5])
>>> a[2]
7
>>> a[-1]
5
>>> a[1:4:2] #(起始编号:终止编号(不含):步长)
array([8, 6])
多维数组的索引
>>> a = np.arange(24).reshape((2, 3, 4))
>>> a
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]]])
>>> a[1, 2, 3]
23
>>> a[0, 1, 2]
6
>>> a[-1, -2, -3]
17
多维数组的切片
>>> a[:, 1, -3] #选取一个维度用:
array([ 5, 17])
>>> a[:, 1:3, :] #每个维度切片方法与一维数组相同
array([[[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[16, 17, 18, 19],
[20, 21, 22, 23]]])
>>> a[:, :, ::2] #每个维度可以使用步长跳跃切片
array([[[ 0, 2],
[ 4, 6],
[ 8, 10]],
[[12, 14],
[16, 18],
[20, 22]]])
ndarray数组的运算
数组与标量之间的运算
数组与标量之间的运算作用于数组的每一个元素
>>> a = np.arange(24).reshape((2, 3 ,4))
>>> a
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]]])
>>> a.mean() #平均值
11.5
>>> a = a / a.mean()
>>> a
array([[[0. , 0.08695652, 0.17391304, 0.26086957],
[0.34782609, 0.43478261, 0.52173913, 0.60869565],
[0.69565217, 0.7826087 , 0.86956522, 0.95652174]],
[[1.04347826, 1.13043478, 1.2173913 , 1.30434783],
[1.39130435, 1.47826087, 1.56521739, 1.65217391],
[1.73913043, 1.82608696, 1.91304348, 2. ]]])
对ndarray中的数据执行元素级运算的函数
一元函数
函数 | 说明 |
---|---|
np.abs(x) np.fabs(x) | 计算数组各元素的绝对值 |
np.sqrt(x) | 计算数组各元素的平方根 |
np.square(x) | 计算数组各元素的平方 |
np.log(x) np.log10(x) np.log2(x) | 计算数组各元素的自然对数、10底对数和2底对数 |
np.ceil(x) np.floor(x) | 计算数组各元素的ceiling值或floor值 |
np.rint(x) | 计算数组各元素的四舍五入值 |
np.modf(x) | 将数组各元素的小数和整数部分以两个独立数组形式返回 |
np.cos(x) | 计算数组各元素的普通型和双曲型三角函数 |
np.exp(x) | 计算数组各元素的指数值 |
np.sign(x) | 计算数组各元素的符号值,1(+),0,-1(-) |
二元函数
函数 | 说明 |
---|---|
| 两个数组各元素进行对应运算 |
np.maximum(x,y) np.fmax() np.minimum(x,y) np.fmin() | 元素级的最大值/最小值计算 |
np.mod(x,y) | 元素级的模运算 |
np.copysign(x,y) | 将数组y中各元素值的符号赋值给数组x对应元素 |
< >= <= == != | 算术比较,产生布尔型数组 |
>>> a = np.arange(24).reshape((2, 3 ,4))
>>> a
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]]])
>>> b = np.sqrt(a)
>>> b
array([[[0. , 1. , 1.41421356, 1.73205081],
[2. , 2.23606798, 2.44948974, 2.64575131],
[2.82842712, 3. , 3.16227766, 3.31662479]],
[[3.46410162, 3.60555128, 3.74165739, 3.87298335],
[4. , 4.12310563, 4.24264069, 4.35889894],
[4.47213595, 4.58257569, 4.69041576, 4.79583152]]])
>>> np.maximum(a, b)
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.]]])
>>> a > b
array([[[False, False, True, True],
[ True, True, True, True],
[ True, True, True, True]],
[[ True, True, True, True],
[ True, True, True, True],
[ True, True, True, True]]])
CSV文件
CSV(Comma-Separated Value,逗号分隔值),CSV是一种常见的文件格式,用来存储批量数据
CSV文件的局限性:只能有效存储一维和二维数组
写入
np.savetxt(frame, array, fmt = '%.18e', delimiter = ',')
- frame:文件、字符串或产生器,可以使.gz或.bz2的压缩文件
- array:存入文件的数组
- fmt:写入文件的格式,例如:%d %.2f %.18e
- delimiter:设定分割字符串,默认是任何空格
读入
np.loadtxt(frame, dtype = np.float, delimiter = ',', unpack = False)
- frame:文件、字符串或产生器,可以使.gz或.bz2的压缩文件
- dtype:数据类型,可选
- delimiter:设定分割字符串,默认是任何空格
- unpack:如果是True,读入属性将分别写入不同变量
多维数组的存取
a.tofile(frame,sep = '', format = '%s')
- frame:文件、字符串
- sep:数据分割字符串,如果是空串,写入文件为二进制
- format:写入数据的格式
np.fromfile(frame, dtype = float, count = -1, sep = '')
- frame:文件、字符串
- dtype:读取数据的类型
- count:读取元素个数,-1表示读入整个文件
- sep:数据分割字符串,如果是空串,写入文件为二进制
该方法需要读取时知道存入文件时数组的维度和元素类型,两者需要配合使用,可以通过元数据文件来存储额外信息
NumPy的便捷文件存取
这种方法可以还原存取原数组的维度和信息
np.save(frame,array) 或 np.savez(frame,array)
- frame:文件名,以.npy为扩展名或压缩扩展名为.npz
- array:数组变量
np.load(frame)
- frame:文件名,以.npy为扩展名或压缩扩展名为.npz
NumPy的随机数子库
NumPy的random子库
函数 | 说明 |
---|---|
rand(d0,d1,…,dn) | 根据d0-dn创建随机数数组,浮点数,[0,1),均匀分布 |
randn(d0,d1,…,dn) | 根据d0-dn创建随机数数组,标准正态分布 |
randint(low[,high,shape]) | 根据shape创建随机整数或整数数组,范围是[low,high) |
seed(s) | 随机数种子,s是给定的种子值 |
>>> a = np.random.rand(2,3,4)
>>> a
array([[[0.61971721, 0.75978775, 0.25187859, 0.89158898],
[0.69988764, 0.79722365, 0.6930626 , 0.33601488],
[0.43248171, 0.37569319, 0.71305447, 0.01714172]],
[[0.10155612, 0.12418438, 0.72925635, 0.83990467],
[0.60069704, 0.45898456, 0.16072765, 0.64881084],
[0.7035746 , 0.63266032, 0.6530597 , 0.05510716]]])
>>> b = np.random.randint(100, 200, (3, 4))
>>> b
array([[133, 152, 159, 169],
[137, 102, 122, 118],
[171, 121, 154, 121]])
函数 | 说明 |
---|---|
shuffle(a) | 根据数组a的第一轴进行随机排列,改变数组a |
permutation(a) | 根据数组a的第一轴产生一个新的乱序数组,不改变数组a |
choice(a[,size,replace,p]) | 从一维数组a中以概率p抽取元素,形成size形状新数组,replace表示是否可以重用元素,默认为True |
>>> b = np.random.randint(100, 200, (3, 4))
>>> b
array([[133, 152, 159, 169],
[137, 102, 122, 118],
[171, 121, 154, 121]])
>>> np.random.shuffle(b)
>>> b
array([[171, 121, 154, 121],
[137, 102, 122, 118],
[133, 152, 159, 169]])
>>> np.random.permutation(b)
array([[171, 121, 154, 121],
[133, 152, 159, 169],
[137, 102, 122, 118]])
>>> b
array([[171, 121, 154, 121],
[137, 102, 122, 118],
[133, 152, 159, 169]])
>>> a = np.random.randint(100, 200, (8,))
>>> a
array([136, 194, 162, 104, 178, 145, 184, 103])
>>> np.random.choice(a, (3, 2))
array([[103, 145],
[136, 136],
[184, 178]])
>>> np.random.choice(a, (3, 2), replace = False)
array([[145, 136],
[103, 194],
[104, 184]])
函数 | 说明 |
---|---|
uniform(low,high,size) | 产生具有均匀分布的数组,low起始值,high结束值,size形状 |
normal(loc,scale,size) | 产生具有正态分布的数组,loc均值,scale标准差,size形状 |
poisson(lam,size) | 产生具有泊松分布的数组,lam随机事件发生率,size形状 |
NumPy的统计函数
NumPy直接提供的统计类函数:
函数 | 说明 |
---|---|
sum(a,axis = None) | 根据给定轴axis计算数组a相关元素之和,axis整数或元组 |
mean(a,axis = None) | 根据给定轴axis计算数组a相关元素的期望,axis整数或元组 |
average(a,axis = None,weights = None) | 根据给定轴axis计算数组a相关元素的加权平均值 |
std(a,axis = None) | 根据给定轴axis计算数组a相关元素的标准差 |
var(a,axis = None) | 根据给定轴axis计算数组a相关元素的方差 |
>>> a = np.arange(15).reshape(3,5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> np.sum(a)
105
>>> np.mean(a, axis = 1)
array([ 2., 7., 12.])
>>> np.mean(a, axis = 0)
array([5., 6., 7., 8., 9.])
>>> np.average(a, axis = 0, weights = [10, 5, 1])
array([2.1875, 3.1875, 4.1875, 5.1875, 6.1875])
>>> np.std(a)
4.320493798938574
>>> np.var(a)
18.666666666666668
函数 | 说明 |
---|---|
min(a) max(a) | 计算数组a中的元素的最小值,最大值 |
argmin(a) argmax(a) | 计算数组a中元素最小值、最大值的降一维后下标 |
unravel_index(index,shape) | 根据shape将一维下标index转换成多维下标 |
ptp(a) | 计算数组a中元素最大值与最小值的差 |
median(a) | 计算数组a中元素的中位数(中值) |
NumPy的梯度函数
梯度:连续值之间的变化率,即斜率
XY坐标轴连续三个X坐标对应的Y轴值:a,b,c,其中,b的梯度是:(c-a)/2
函数 | 说明 |
---|---|
np.gradient(f) | 计算数组f中元素的梯度,当f为多维时,返回每个维度梯度 |
>>> a
array([ 2, 14, 7, 5, 2])
>>> np.gradient(a)
array([12. , 2.5, -4.5, -2.5, -3. ])
>>> b = np.random.randint(0, 50,(3,5))
>>> b
array([[36, 34, 27, 4, 41],
[ 3, 22, 16, 46, 42],
[23, 39, 25, 22, 29]])
>>> np.gradient(b)
[array([[-33. , -12. , -11. , 42. , 1. ],
[ -6.5, 2.5, -1. , 9. , -6. ],
[ 20. , 17. , 9. , -24. , -13. ]]),
array([[ -2. , -4.5, -15. , 7. , 37. ],
[ 19. , 6.5, 12. , 13. , -4. ],
[ 16. , 1. , -8.5, 2. , 7. ]])]