python科学计算基础库——numpy
- numpy库的主要内容为一个强大的多维数组对象ndarray
- 广播功能函数
- 整合C/C++/Fortran代码的工具
- 线性代数、傅里叶变换、随机数生成等功能
常用一维及二维数组对象,故不对三维及以上数组进行说明
导入
import numpy as np
关于数组
- 数组中所有数据的类型必须相同
- 数组的运算效率远高于列表
- 多维数组可以表现为多重嵌套列表
- 数组可以理解为一系列容纳元素的小格子
- 一维数组就是一排小格子
- 二维数组是有n行、m列的长方形格子阵(即矩阵)
创建数组
# t = np.array(object, dtype=None)
# t = np.arange(start, stop, step, dtype=None)
np.array将其他类型的对象转换为数组
np.arange()等价于np.array(range()),用于快速创建一个一维数组
数组的属性
- ndarray.ndim:返回数组的维数
- ndarrry.dtype:返回数组内数据的类型
- ndarray.shape:返回数组的形状
- ndarray.size:返回数组中元素的个数
ndarray的数据类型
- int32、int64等, 不同位整型
- float32、float64等,不同精度的浮点数
- complex64、complex128等,用两个不同位数的浮点数表示的复数
- bool, 存储True和False值的布尔类型
- object, python对象类型
- string, 字符串类型
- unicode, 固定长度的Unicode类型
数组的广播机制
数组的计算有如下现象:
t1 = np.arange(4)
t2 = np.arange(12).reshpe(3, 4)
t1
array([0, 1, 2, 3])
t2
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
t1-1
array([-1, 0, 1, 2])
t2-t1
array([[0, 0, 0, 0],
[4, 4, 4, 4],
[8, 8, 8, 8]])
可以发现,当数组与一常数进行计算时,与常数的计算被应用到了数组的每一个元素;
当一个二维数组与一个长度和二维数组的列数相同的一维数组计算时,二维数组的每一行作为元素与其进行计算.
++这就是通过广播机制实现的++
广播的原则:如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符,或其中的一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
总之,如果某一维数组的size为某二维数组shape中的一个数字,则两者可以进行数学运算
数组的轴
’轴‘这个概念针对二维及以上数组
aixs=0为竖轴,指每一列的方向
aixs=1为横轴,指每一行的方向
数组的切片与索引
数组的索引和列表一样,从0开始
一维数组的索引与切片与列表完全相同,不再赘述
t = np.arange(12).reshape(3, 4)
t
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# 当t[]内只传入一组参数时,默认取行
t[0]
array([0, 1, 2, 3])
t[::-1]
array([[ 8, 9, 10, 11],
[ 4, 5, 6, 7],
[ 0, 1, 2, 3]])
# 要单独取列时,要先对行进行全选
t[:, :2]
array([[0, 1],
[4, 5],
[8, 9]])
# 取不连续的行和列时,传入列表以指定
t[:, [1, 3]]
array([[ 1, 3],
[ 5, 7],
[ 9, 11]])
# 当行和列都传入了列表是,会对两个列表进行解包重组
t[[0, 1], [1, 2]]
array([1, 6]) # 即(0,1)和(1, 2)两个元素
# 以上不止可以传入列表,还可以传入一维数组和元组
# 取某一位置的值
t[2,2]
10
t[(2,2)]
10
# 布尔索引
# 1,当数组进行布尔运算
t > 6
array([[False, False, False, False],
[False, False, False, True],
[ True, True, True, True]])
# 2,当切片时传入类型为bool的列表
t[[True, True, False]] # True取,False不取
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
t[:, [False, True, False, True]]
array([[ 1, 3],
[ 5, 7],
[ 9, 11]])
# 当1和2组合起来
t[t>6]
array([ 7, 8, 9, 10, 11])
切片返回的是源对象的view,通过赋值可以实现元素的修改
数组对象的基本方法
- ndarray.astype():改变数组的dtype,返回一个新数组
- ndarray.reshape():改变数组的形状,返回一个新数组
- ndarray.ravel():返回数组的一维view
- ndarray.flatten():返回数组的一维copy
t = np.arange(12)
t
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
t = t.astype(float)
t
array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.])
t = t.reshape(3, 4)
t
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
t.ravel()
array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.])
t.ravel()[11] = np.nan # 通过view可以对源对象进行修改
t
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., nan]])
nan和inf
nan:not a number
inf:infinity,无穷
type(np.nan) ,type(np.inf)
(float, float)
什么时候会出现nan?
对浮点数进行了未定义的操作
- 对负数开方,对负数求对数,0.0/0.0,0.0*inf、inf/inf、inf-inf这些操作都会得到nan。(0/0会产生操作异常;0.0/0.0不会产生操作异常,而是会得到nan);
- 当我们读取本地文件为float的时候,如果有缺失,就会出现nan
什么时候会出现inf?
超出浮点数的表示范围(溢出,即阶码部分超过其能表示的最大值);
- 1.0/0.0等于inf,-1.0/0.0等于-inf
- 0.0+inf=inf;log(0)
如何选中数组中的nan并将其替换为0
t = np.array([0, 1, 1, 2, 0, 3, 0]).astype(float)
t = t/t
t
array([nan, 1., 1., 1., nan, 1., nan])
# 1, 利用特性 nan != nan
t[t!=t] = 0
t
array([0., 1., 1., 1., 0., 1., 0.])
# 2,利用函数np.isnan(ndarray)
t = t/t
t[np.isnan(t)]=0
array([0., 1., 1., 1., 0., 1., 0.])
常用统计函数
- ndarray.max(axis=None) # 最大值
- ndarray.min(axis=None) # 最小值
- ndarray.mean(axis=None) # 平均值
- ndarray.median(axis=None) # 中位数
- ndarray.ptp(axis=None) # 极差
- ndarray.std(axis=None) # 标准差
- ndarray.cumsum()累计和
- ndarray.cumprod()累计积
当不传入axis参数时,运算对象为整个数组
axis=0,对每一列进行运算
axis=1,对每一行进行计算
t = np.arange(100).reshape(10,10)
t
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, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])
t.sum()
4950
t.sum(axis=0)
array([450, 460, 470, 480, 490, 500, 510, 520, 530, 540])
t.sum(axis=1)
array([ 45, 145, 245, 345, 445, 545, 645, 745, 845, 945])
t0 = t[0]
t0
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
t0.cumsum()
array([ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45], dtype=int32)
np.random
numpy的random模块能快速生成指定形状的随机数组
- np.random.rand()生成均匀分布的随机数,范围为0~1
- np.random.randn()生成标准正态分布随机数组成的数组(mean=0, sigma=1)
- 传入的参数表示数组的形状
- 如np.random.rand(3, 4)表示生成一个三行四列的随机数数组
- np.random.randint(low, high, (shape), dtype)从给出的上下限[low, high)中随机选取整数组成指定形状的数组
- np.random.uniform(low, high, (shape)) 从上下限中选取具有均匀分布特征的数据
其他的通用函数
- np.abs(array) / np.fabs(array)
取绝对值,对于非复数数值,可以用速度更快的fabs - np.sqrt(array)
计算平方根,即array**0.5 - np.square(array)
计算平方, 即array**2 - np.ceil(array)
向上取整 - np.floor(array)
向下取整 - np.sin()、np.cos、np.tan()等
三角函数,传入参数返回对应函数值