- SciPy从广义上来讲代表使用 Python 进行数学、科学和工程开发的开源软件生态系统,其包含: NumPy, Pandas,Matplotlib, SymPy,IPython 等一系列核心库和工具。
- 狭义上 特指* SciPy 核心库*, 其基于 NumPy 构建,继承了 NumPy 对多维数据的高效计算能力。从某种意义上将,SciPy 可以被看作是 NumPy 的拓展和补充。
常量模块 scipy.constants
from scipy import constants
print("圆周率: ", constants.pi)
# 圆周率: 3.141592653589793
print("黄金分割常数: ", constants.golden)
# 黄金分割常数: 1.618033988749895
线性代数 Linear algebra ( scipy.linalg )
线性代数计算函数
大致分为:基本求解方法,特征值问题,矩阵分解,矩阵函数,矩阵方程求解,特殊矩阵构造等几个小类。
矩阵的逆 scipy.linalg.inv
设A是数域上的一个n阶方阵,若在相同数域上存在另一个n阶矩B,使得: AB = BA = E。 则我们称B是A的逆矩阵,而A则被称为可逆矩阵。其中,E为单位矩阵。
import numpy as np
from scipy import linalg
A = np.matrix([[1, 2], [3, 4]])
# 求矩阵A的逆矩阵
B = linalg.inv(A)
E = A * B
E
# [[1,0],[0,1]]
奇异值分解 scipy.linalg.svd
奇异值分解(Singular Value Decomposition)是线性代数中一种重要的矩阵分解,奇异值分解则是特征分解在任意矩阵上的推广。在信号处理、等领域有重要应用。
应用
- 求伪逆
奇异值分解可以被用来计算矩阵的伪逆。若矩阵 M 的奇异值分解为M = UΣV,那么 M 的伪逆为 M+ = UΣ+V。
其中Σ+是Σ的伪逆,是将其主对角线上每个非零元素都求倒数之后再转置得到的。求伪逆通常可以用来求解线性最小平方、最小二乘法问题。- 平行奇异值
把频率选择性衰落信道进行分解。- 矩阵近似值
在统计中的主要应用为主成分分析(PCA),一种数据分析方法,用来找出大量数据中所隐含的“模式”,它可以用在模式识别,数据压缩等方面。PCA算法的作用是把数据集映射到低维空间中去。 数据集的特征值(在SVD中用奇异值表征)按照重要性排列,降维的过程就是舍弃不重要的特征向量的过程,而剩下的特征向量组成的空间即为降维后的空间。
A = np.random.randn(5, 4)
U, s, Vh = linalg.svd(A)
U, s, Vh
- 最终返回酉矩阵 U 和 Vh,以及奇异值 s。
最小二乘法求解函数 scipy.linalg.lstsq
最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小
最小二乘法还可用于曲线拟合,其他一些优化问题也可通过最小化能量或最大化熵用最小二乘法来表达
- 假设x, y 满足 y = a*x^2 + b
- 求满足条件的参数[a,b],使得 f(x) = a*x^2 + b
1. 首先,我们给出样本的 和 值
x = np.array([1, 2.5, 3.5, 4, 5, 7, 8.5])
y = np.array([0.3, 1.1, 1.5, 2.0, 3.2, 6.6, 8.6])
2. 接下来,我们完成 2 计算,并添加截距项系数 1
M = x[:, np.newaxis]**[0, 2]
3. 然后使用`linalg.lstsq` 执行最小二乘法计算,返回的第一组参数即为拟合系数。
p = linalg.lstsq(M, y)[0]
# f(x) = p[0] + p[1]*x^2
- 观测值 和 拟合曲线的可视化
plt.scatter(x,y) # 观测值
xx = np.linspace(0, 10, 100)
y_pred = p[0] + p[1]*xx**2
plt.plot(xx, y_pred)
插值函数 scipy.interpolate
插值,是数值分析领域中通过已知的、离散的数据点,在范围内推求新数据点的过程或方法。
线性插值 interpolate.interp1d
x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
y = np.array([0, 1, 4, 9, 16, 25, 36, 49, 64, 81])
from scipy import interpolate
xx = np.array([0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5]) # 两点之间的点的 x 坐标
f = interpolate.interp1d(x, y) # 使用原样本点建立插值函数
yy = f(xx) # 映射到新样本点(插值点)
plt.scatter(x, y)
plt.scatter(xx, yy, marker='*')
- 可以看到,星号点是我们插值的点,而圆点是原样本点,插值的点能准确符合已知离散数据点的趋势
图像处理 scipy.ndimage
SciPy 集成了大量针对图像处理的函数和方法。当然,一张彩色图片是由 RGB 通道组成,而这实际上就是一个多维数组。所以,SciPy 针对图像的处理的模块 scipy.ndimage
,实际上也是针对多维数组的处理过程,你可以完成卷积、滤波,转换等一系列操作。
高斯滤波 scipy.ndimage.gaussian_filter
from scipy import misc
face = misc.face()
plt.imshow(face)
from scipy import ndimage
plt.imshow(ndimage.gaussian_filter(face, sigma=5))
旋转变换 ndimage.rotate
plt.imshow(ndimage.rotate(face, 45))
卷积操作 ndimage.convolve
# 首先随机定义一个卷积核 k,
k = np.random.randn(2, 2, 3)
# 然后再执行卷积
plt.imshow(ndimage.convolve(face, k))
优化方法 scipy.optimize
最优化,是应用数学的一个分支,一般我们需要最小化(或者最大化)一个目标函数,而找到的可行解也被称为最优解。
机器学习算法都会有一个目标函数,我们也称之为损失函数。而找到损失函数最小值的过程也就是最优化的过程。我们可能会用到最小二乘法,梯度下降法,牛顿法等最优化方法来完成。
非线性的最小二乘法问题 scipy.optimize.least_squares
def func(p, x):
'''拟合函数'''
w0, w1 = p # 拟合的参数
f = w0 + w1*x*x # f(x) = w1*x^2 + w0
return f
def err_func(p, x, y):
'''残差函数'''
ret = func(p, x) - y
return ret
# 最小二乘拟合
from scipy.optimize import leastsq
# 参数初始化
p_init = np.random.randn(2) # 生成 2 个随机数
x = np.array([1, 2.5, 3.5, 4, 5, 7, 8.5])
y = np.array([0.3, 1.1, 1.5, 2.0, 3.2, 6.6, 8.6])
# 使用 Scipy 提供的最小二乘法函数得到最佳拟合参数
parameters = leastsq(err_func, p_init, args=(x, y))
parameters[0]
# array([0.20925827, 0.12013861])
信号处理 scipy.signal
是指对信号表示、变换、运算等进行处理的过程,信号处理在诸如语音与数据通信、生物医学工程、声学、声呐、雷达、地震、石油勘探、仪器仪表、机器人、日用电子产品以及其它很多的这样一些广泛的领域内起着关键的作用。
模块被划分为:卷积,B-样条,滤波,窗口函数,峰值发现,光谱分析等 13 个小类,共计百余种不同的函数和方法。所以说,信号处理是 SciPy 中十分重要的模块之一。
生成 高斯调制正弦波、锯齿波、方波
from scipy import signal
fig,axis = plt.subplots(1,3,figsize = (12,3)) # 每个图片 figsize(4,3)
# 高斯调制正弦波
t = np.linspace(-1,1,100)
axis[0].plot(t, signal.gausspulse(t, fc = 5, bw = 0.5))
axis[0].set_title("gausspulse")
# 锯齿波
t = 5*np.pi*t
axis[1].plot(t, signal.sawtooth(t))
axis[1].set_title("chirp")
# 方波
axis[2].plot(t, signal.square(t))
axis[2].set_title("gausspulse")
滤波函数
- 中值滤波函数
scipy.signal.medfilt
- 维纳滤波函数
scipy.signal.wiener
def f(t):
return np.sin(np.pi*t) + 0.1*np.cos(7*np.pi*t+0.3) + \
0.2 * np.cos(24*np.pi*t) + 0.3*np.cos(12*np.pi*t+0.5)
t = np.linspace(0, 4, 400)
plt.plot(t, f(t))
# 中值滤波
y_med = signal.medfilt(f(t), kernel_size=55)
plt.plot(t, y_med , linewidth=2, label="medfilt")
# 维纳滤波
y_wie = signal.wiener(f(t), mysize=55)
plt.plot(t, y_wie , linewidth=2, label="wiener")
plt.legend()
统计函数 scipy.stats
统计理论应用广泛,尤其是和计算机科学等领域形成的交叉学科,为数据分析、机器学习等提供了强大的理论支撑。
scipy.stats
模块包含大量概率分布函数,主要有连续分布、离散分布以及多变量分布。除此之外还有摘要统计、频率统计、转换和测试等多个小分类。基本涵盖了统计应用的方方面面。
正态分布 scipy.stats.norm
- norm.rvs 返回随机变量
- norm.pdf 返回概率密度函数
- norm.cdf 返回累计分布函数
- norm.sf 返回残存函数
- norm.ppf 返回分位点函数
- norm.isf 返回逆残存函数
- norm.stats 返回均值,方差,(费舍尔)偏态,(费舍尔)峰度
- norm.moment 返回分布的非中心矩。
基于概率密度函数绘制出正态分布曲线
x = np.linspace(norm.ppf(0.01), norm.ppf(0.99), 1000)
plt.plot(x, norm.pdf(x))
稀疏矩阵 scipy.sparse
数值分析中,元素大部分为零的矩阵被称为 稀疏矩阵。通过压缩稀疏矩阵可以大大节省稀疏矩阵的内存代价。更为重要的是,由于过大的尺寸,标准的算法经常无法操作这些稀疏矩阵。
scipy.sparse
中大致有七类稀疏矩阵储存方法,分别为:
-
csc_matrix
压缩稀疏列矩阵 -
csr_matrix
压缩稀疏行矩阵 -
bsr_matrix
块稀疏行矩阵 -
lil_matrix
基于行的链表稀疏矩阵 -
dok_matrix
基于字典稀疏矩阵 -
coo_matrix
坐标格式的稀疏矩阵 -
dia_matrix
对角线稀疏矩阵。
压缩稀疏列矩阵
可以看到,稀疏矩阵保存时,实际上是通过坐标的形式表示出矩阵中非零元素的位置。
from scipy.sparse import csr_matrix
array = np.array([[2, 0, 0, 3, 0, 0],
[1, 0, 1, 0, 0, 2],
[0, 0, 1, 2, 0, 0]])
csr = csr_matrix(array)
print(csr)
(0, 0) 2
(0, 3) 3
(1, 0) 1
(1, 2) 1
(1, 5) 2
(2, 2) 1
(2, 3) 2
变为稠密矩阵表示
csc.todense()
matrix([[2, 0, 0, 3, 0, 0],
[1, 0, 1, 0, 0, 2],
[0, 0, 1, 2, 0, 0]], dtype=int64)