NumPy(Numerical Python)是Python用于数值计算的基础包
- 内置高效的多维数组
ndarray
,提供快速向量计算和灵活的广播机制 - 具备常见的数学计算函数(线性代数、傅里叶变换等)和读写数据的能力
- 在一个连续的内存块中存储数据,节省内存并且计算效率高
- 提供动态、易用的接口,也很方便与其他常用编程语言对接
关于广播机制可参阅1.3 广播机制
1 多维数组
ndarray
数组是一个通用的同构数据多维容器,即所有元素的类型应该是相同的
数组基本操作:
import numpy as np # 库重命名
data = np.random.randn(2, 3) # 随机生产2*3的数组
data = data * 10 + data # 基本向量运算
data.shape # 查看数组维度
data.dtype # 查看元素类型
data.astype(str) # 转换元素类型
data = np.array([[1, 2, 3], [6, 7, 8]]) # 列表转数组
data[2:,:-1].copy() # 支持灵活的切片操作(第2行以后,倒数第1列之前)
data[~(data < 6)] = 1 # 过滤与复制,~用来表示非这一逻辑操作
细节补充:
- 尽量不要在numpy中使用
str
格式,因为其内部空间是固定的,所以可能出现数据截断的问题- 当数据与指定格式不兼容时,
astype
可能会报错;转换成功后会生成一个新对象(即使格式前后一样)- 数组的切片操作其实是一种视图,并不会复制数据(减少内存负担),使用
copy()
可以显式复制数据- Python在进行逻辑操作时会使用
and
和or
等关键字,但在数组中要使用&
和|
来实现
内置函数用于便捷地生成矩阵:ones
全1矩阵、zeros
全0矩阵、empty
空矩阵、eye
单位矩阵
数组操作常用:
dara.T # 数组转置
data.reshape((3,2)) # 数组维度变换
np.dot(data.T, data) # 计算矩阵点积
arr = np.arange(16).reshape((2, 2, 4))
arr.transpose((0, 2, 1)) # 轴变换(2轴变3轴,3轴变2轴)
arr.swapaxes(1, 2) # 指定两个轴进行转置(也是视图操作)
2 伪随机数生成
# 从标准正态分布中得到一个4 × 4的样本数组
samples = np.random.standard_normal(size=(4, 4))
new_samples = np.random.permutation(samples) # 随机打乱
np.random.shuffle(samples) # 原地随机打乱
除了标准正态分布,
numpy
的随机生成还支持uniform
均匀分布、integers
整数随机、binomial
二项分布、normal
普通正态、beta
贝塔分布、chisquare
卡方分布、gamma
伽马分布
numpy的随机数是基于生成器种子进行的伪随机,可通过
seed
固定随机种子,方便结果的复现
3 数组相关通用函数
通用函数(Universal Functions,简称ufunc)是指针对数组每个元素进行运算的函数(矢量化运算)
常见一元ufunc:abs
绝对值、fabs
绝对值(对于非复数,更快)、sqrt
开方、aquare
平方、exp
指数、log,log10,log2
不同底数的对数(默认为e)、sign
正负号、ceil
向上取整、floor
向下取整、modf
切分整数和小数部分、isna
判断是否为空、isinf
判断是否为无穷、sin,cos,tan,sinh,cosh,tanh
常见三角函数
常见二元ufunc(输入项为两个数组):add
元素相加、subtract
元素相减、multiply
元素相乘、divide
元素相除、floor_divide
元素整除(丢弃余数)、power
底数^指数、maximum,fmax
比较取最大、minimum,fmin
比较取最小、mod
求模(取余数)、copysign
元素替换(后者替代前者)、>,<,==,!=,
逻辑运算
4 数组相关数据分析
用数组表达式代替循环的做法被称为矢量化(vectorization),相比于循环效率会高很多
# 数据初始化
xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
# 按照条件筛选两组数据
result = [(x if c else y) for x, y, c in zip(xarr, yarr, cond)]
# 数组的矢量化等价写法
result = np.where(cond, xarr, yarr)
常用聚合计算:mean
均值、var,std
方差/标准差、sum
求和、cumsum
累积加、cumprod
累积乘、min
最小值、max
最大值、argmin
最小值对应位置、argmax
最大值对应位置、any
数组内元素or
运算、all
数据内元素and
运算
聚合运算可以通过参数
axis
指定轴,以进行不同维度的聚合
集合相关运算:sort
排序、unique
去重、intersect1d(x,y)
计算x和y的公共元素并排序、union1d(x,y)
计算x和y的并集并排序、in1d(x,y)
判断x中元素是否属于y、setdiff1d(x,y)
在x中且不属于y的元素、setxor1d(x,y)
在其中一个数组中存在且不同时存在于两个数组的元素
5 数组的存储与读取
数组的存储与读取示例:
arr = np.arange(10)
np.save('some_array', arr) # 普通存储
np.load('some_array.npy') # 普通读取
np.savez('array_archive.npz', a=arr, b=arr) # 多数组存储
np.load('array_archive.npz')['b'] # 多数组读取
np.savez_compressed('arrays_compressed.npz', a=arr, b=arr) # 多数组压缩存储
6 数组与线性代数
矩阵乘法示例:
x = np.array([[1., 2., 3.], [4., 5., 6.]])
y = np.array([[6., 23.], [-1, 7], [8, 9]])
x.dot(y) # 矩阵乘法 写法1
np.dot(x,y) # 矩阵乘法 写法2
x @ np.ones(3) # 矩阵乘法 写法3
其他常用矩阵运算:diag
获取对角线元素、trace
对角线求和、det
计算行列式、eig
计算特征值和特征向量、inv
矩阵求逆、pinv
广义逆矩阵(伪逆)、qr
正交三角分解、svd
奇异值分解、solve
求解线性方程组、lstsq
计算Ax = b最小二乘解
7 案例:随机游走
纯Python实现一次随机游走:
import random
position = 0
walk = [position]
steps = 1000
for i in range(steps):
step = 1 if random.randint(0, 1) else -1
position += step
walk.append(position)
numpy实现一次随机游走:
nsteps = 1000
draws = np.random.randint(0, 2, size=nsteps)
steps = np.where(draws > 0, 1, -1)
walk = steps.cumsum()
numpy实现5000次随机游走:
nwalks = 5000
nsteps = 1000
draws = np.random.randint(0, 2, size=(nwalks, nsteps)) # 0 or 1
steps = np.where(draws > 0, 1, -1)
walks = steps.cumsum(1)