自学Python

Chapter 8

第8章Python科学计算进阶:SciPy模块

章节主张

第8章Python科学计算进阶:SciPy模块这一章真正要建立的,不是孤立知识点,而是围绕“SciPy 把高等数学能力接进代码、环境与工具链先于语法细节、函数与模块是从会写到会组织的分水岭”形成一套能反复练习、能迁移到真实任务里的 Python 学习路径。

中文释读

读 第8章Python科学计算进阶:SciPy模块 时,不要只把它当作语法或模块说明书。更有价值的读法,是问自己:这一章解决了我在编程、科学计算或数据分析流程中的哪个瓶颈?

这本书的强项在于把工具、基础语法、科学计算库和案例工作流连成一条线。章节页因此会把原书内容翻译成“知识点 -> 操作动作 -> 易错边界 -> 迁移练习”的学习结构。

本章知识路线

关键论据

  • Anaconda中已经集成了SciPy模块。
  • 可以在命令行使用pip命令更新模块: SciPy是基于NumPy构建的,通常的导入方式为: 本书使用的SciPy模块版本为: SciPy模块由很多不同的科学计算子模块组成,常用的模块如下。
  • ●scipy.cluster:聚类算法。
  • ●scipy.integrate:积分和常微分方程求解。
  • ●scipy.interpolate:插值相关。

行动清单

  • 先用最小代码样例跑通本章核心知识点。
  • 把本章知识点接到一个真实小任务上,而不只停留在示例。
  • 记录本章最容易报错的边界条件和调试方式。
  • 复盘:这一章内容如何进入自己的长期 Python 学习系统。

本章图版学习路径

图版按知识点分组,适合拿来做复现、迁移和复盘练习,不只是“看一眼效果”。

源章节深读

8.1 SciPy模块简介

这节解决什么问题:这节要解决的不是背下“8.1 SciPy模块简介”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“8.1 SciPy模块简介”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 8.1 SciPy模块简介 背后的对象模型、输入输出和适用边界。

Anaconda中已经集成了SciPy模块。可以在命令行使用pip命令更新模块: SciPy是基于NumPy构建的,通常的导入方式为: 本书使用的SciPy模块版本为: SciPy模块由很多不同的科学计算子模块组成,常用的模块如下。 ●scipy.cluster:聚类算法。 ●scipy.integrate:积分和常微分方程求解。 ●scipy.interpolate:插值相关。 ●scipy.optimize:优化相关。 ●scipy.stats:统计相关。 ●scipy.linalg:线性代数相关。 SciPy模块通常以“子模块.函数”的形式进行调用:

8.2 插值模块:scipy.interpolate

这节解决什么问题:这节要解决的不是背下“8.2 插值模块:scipy.interpolate”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“8.2 插值模块:scipy.interpolate”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 8.2 插值模块:scipy.interpolate 背后的对象模型、输入输出和适用边界。

scipy.interpolate是SciPy中负责插值操作的子模块。导入interpolate子模块: 插值 (Interpolation)是通过已知的离散数据点求数据的过程或方法。在实际问题中,对于若干离散的数据点(x,y),可以通过某种方法得到一个经过所有已知数据点的连续函数y=f(x),然后通过该函数预测点x'的对应值f(x')。例如,考虑这样一组离散数据点: 该组数据由三角函数生成,分布如图8-1所示: 图8-1 待插值的一组离散数据点 1.一维插值函数 这些数据点x的维度为1,因此是个一维插值问题。一维插值问题对应的函数为interpolate. interp1d()。该函数接受一组x值和对应的y值,返回拟合后得到的函数: 返回值f可以像函数一样被调用。当输入值为数字时,f返回一个NumPy数组: 输入值为数组或列表时,f返回对应大小的数组: 默认情况下,插值函数允许的定义域范围由输入数据的范围决定。对于超出范围的数据,调用f会抛出异常。例如,在上面的例子中,x的范围为圆周率的0~2倍,因此输入负数会报错: 可以通过在调用插值函数时加入bounds_error参数来允许超出范围的输入: 若输入值超过插值范围,输出为np.nan: 还可以加入fill_value参数来指定超出范围的默认返回值: 2.不同的插值方法 (1)线性插值方法 线性插值 (Linear Interpolation)是最常使用的插值方法,也是插值函数的默认方法。线性插值的基本思想为:在已知相邻点(x 1 ,y 1 )和(x 2 ,y 2 )的情况下,对于x 1 ~x 2 的任意x,线性插值对应的y满足点(x,y)在点(x 1 ,y 1 )和(x 2 ,y 2 )所形成的线段上。 对于之前的数据点,线性插值方法对应的

8.3 概率统计模块:scipy.stats

这节解决什么问题:这节要解决的不是背下“8.3 概率统计模块:scipy.stats”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“8.3 概率统计模块:scipy.stats”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 8.3 概率统计模块:scipy.stats 背后的对象模型、输入输出和适用边界。

scipy.stats是Scipy中负责概率统计相关的子模块。 先看基本统计量的计算,导入相关的模块: 假设有一组身高数据: NumPy数组提供了一些方法来查看这组数据的基本统计量,如最大最小值: 平均值: 标准差和方差: 中位数: scipy.stats模块提供了一些其他的统计量,如众数及其出现次数: 偏度和峰度: 概率分布 (Probability Distribution)是统计和概率论中的一个重要组成部分,scipy.stats模块提供了一些函数和方法来使用这些概率分布。导入相关模块: 概率分布可以分为连续分布和离散分布两大类。不同的概率分布定义和参数各不相同,不过,scipy.stats模块提供了一套公用的接口来处理它们。 1.连续分布 (1)正态分布 正态分布对象norm可以直接导入: 可以用方法.rvs()来产生一个服从标准正态分布的数组: 标准正态分布数据的直方图如图8-5所示: 图8-5 标准正态分布数据的直方图 数学上,正态分布有两个参数,分别为均值和标准差。可以使用.fit()方法估计上面这组数据对应的正态分布参数:

8.4 优化模块:scipy.optimize

这节解决什么问题:这节要解决的不是背下“8.4 优化模块:scipy.optimize”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“8.4 优化模块:scipy.optimize”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 8.4 优化模块:scipy.optimize 背后的对象模型、输入输出和适用边界。

scipy.optimize是SciPy中负责优化的子模块,这里介绍其三个主要功能: ●最小二乘优化和曲线拟合。 ●无约束的优化。 ●方程求根。 导入基础的模块: 1.多项式拟合 多项式拟合 (Polynomial Curve-Fitting)用n阶多项式描述数据点( x , y )的关系: 多项式拟合的目的是找到一组系数 a ,使得拟合得到的曲线与真实数据点之间的距离最小。例如,考虑 n =1(即线性拟合)的情况,一组待拟合的数据点如图8-14所示: 拟合与插值不同,拟合不要求得到的曲线经过所有的数据点。多项式拟合的系数可以使用NumPy模块的np.polyfit()函数来得到: 其中,n为多项式阶数。一阶多项式函数为 y=a 1 x+a 0 n=1时,返回一阶多项式的两个系数: 图8-14 一阶多项式拟合数据 拟合得到的系数与生成数据时所用的4和1.5比较接近,说明拟合有一定的效果。拟合得到的曲线如图8-15所示: 图8-15 线性拟合结果 多项式函数还可以通过np.ploy1d()函数生成: 生成的多项式对象支持数学运算得到新的多项式: 再看更高阶的多项式拟合问题。例如,有这样一组正弦函数的数据点:

8.5 线性代数模块:scipy.linalg

这节解决什么问题:这节要解决的不是背下“8.5 线性代数模块:scipy.linalg”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“8.5 线性代数模块:scipy.linalg”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 8.5 线性代数模块:scipy.linalg 背后的对象模型、输入输出和适用边界。

scipy.linalg是SciPy中负责线性代数计算的模块。NumPy也有numpy.linalg模块,不过建议使用scipy.linalg,原因有二: ●scipy.linalg包含numpy.linalg中的所有函数,同时还包含了很多numpy.linalg中没有的函数。 ●scipy.linalg默认使用线性代数库BLAS/LAPACK等对运算进行加速,而在numpy.linalg中,这些加速需要自己配置,不是默认设置的。 具体的比较如下: 先导入相关的模块: 1.基本的矩阵操作 在NumPy中,矩阵有两种表示方法:矩阵类型和二维数组类型。 (1)矩阵类型下的基本操作 矩阵类型可以用np.mat()或者np.matrix()创建: 对于矩阵类型,它的转置矩阵为: 通常把形状为n×n的矩阵称为 方阵 (Square Matrix)。对于一个方阵A,如果方阵B满足AB = BA = I,称方阵B是A的 逆矩阵 (Inverse Matrix),其中I是单位矩阵。 单位矩阵 (Identity Matrix)是指对角线元素为1其余元素为0的矩阵。如果逆矩阵存在,对于矩阵类型,它的逆矩阵可以用.I属性查看: 左乘逆矩阵: 右乘逆矩阵: (2)二维数组类型下的基本操作 矩阵也可以用二维数组对象表示,数组对象的矩阵操作与矩阵对象有一定的区别。首先创建数组: 用.T属性得到数组的转置: 数组没有.I属性,其逆矩阵可以用linalg.inv()函数计算: 数组的矩阵乘法需要使用.dot()方法或者运算符“@”进行计算:

8.6 实例:基于SciPy的主成分分析

这节解决什么问题:这节要解决的不是背下“8.6 实例:基于SciPy的主成分分析”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“8.6 实例:基于SciPy的主成分分析”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 8.6 实例:基于SciPy的主成分分析 背后的对象模型、输入输出和适用边界。

通过SciPy模块,可以实现一种常用的数据分析技术——主成分分析。 主成分分析 (Principal Component Analysis,PCA)是一种常用的数据分析简化方法,通常用于降低数据的维度。 本节将主成分分析定义为一个函数,该函数接受一个数组X和维度k为输入,返回对数组X进行主成分分析后的新数组Y。按照主成分分析的算法,函数的具体计算流程如下: ●第一步,计算数组X每个维度的均值和标准差。 ●第二步,将数组X零均值化和方差归一化得到X。 ●第三步,计算处理后数据的协方差矩阵 ∑ 。 ●第四步,对协方差矩阵 ∑ 进行特征值分解。 ●第五步,取前k大的特征值对应的特征向量为主成分矩阵U k 。 ●第六步,计算XU k ,该乘积为主成分分析得到的结果。 根据需要,首先导入相关模块: 定义函数pca: 其中,输入参数X的形状为(N,d),表示N个d维数据点;k是一个整数,表示输出的维度;函数返回值的形状为(N,k)。按照流程,第一步,使用数组的方法.mean()与.std()计算X各个维度的均值和标准差,返回的均值m和方差s都是大小为d的一维数组: 第二步,利用均值和方差对数据进行零均值和归一化: 其中,np.spacing()函数用来防止方差s出现除数为0的情况。Np.spacing(x)函数返回的是x与离x最近的浮点数的绝对值,np.spacing(0)的值大约为4.94e-324。 第三步,计算新数据的协方差矩阵,零均值的情况下,协方差矩阵的计算为: 第四步,用scipy.linalg中的linalg.eig()函数对协方差矩阵进行特征值分解: U是由特征向量组成的矩阵,每一列对应一个特征值。 第五步,取U中对应的前k个特征向量组成主成分矩阵Uk: 第六步,Uk的形状为(d,k),通过

8.7 本章学习笔记

这节解决什么问题:这节要解决的不是背下“8.7 本章学习笔记”,而是把这个知识点放进真正可运行、可调试、可迁移的 Python 学习流程里。

怎么用到自己的系统:把它写进自己的学习系统:先用最小例子跑通,再把“8.7 本章学习笔记”迁移到一个实际小任务中,最后记录哪些边界条件最容易报错。

常见错误:常见误区是只记住 API 或代码片段,却没理解 8.7 本章学习笔记 背后的对象模型、输入输出和适用边界。

本章完成了SciPy模块的介绍。SciPy模块在NumPy模块的基础上,包含了很多进阶的科学计算操作,需要有一定的高等数学基础才能灵活使用。 学完本章,读者应该做到: ●了解SciPy的基本用法。 ●知道SciPy各个模块的功能和使用方法。 1.本章新术语 本章涉及的新术语见表8-1。 表8-1 本章涉及的新术语 (续) 2.本章新函数 本章涉及的新函数见表8-2。 表8-2 本章涉及的新函数 3.本章Python 2与Python 3的区别 本章不涉及Python 2与Python 3的区别。

辨析题:如果你只会照抄 第8章Python科学计算进阶:SciPy模块 里的例子,却无法换一个输入自己写出来,真正缺的是什么?

多数时候缺的不是记忆,而是对象模型、输入输出边界和操作顺序的理解。把知识点换到新输入上依然能运行,才算真的进入了自己的系统。