跳转至

Python

Python 进阶教程系列 4:命令行参数

本文是 Python 进阶教程系列 4,主要介绍了 sysargparse 解析命令行参数。

命令行参数是指在运行程序时传递给程序的参数。例如,我们可以通过命令行参数来指定要处理的文件名、设置程序的配置选项等。

image-20230727235705211

Python 进阶教程系列 3:生成器

本文是 Python 进阶教程系列 3,主要介绍了生成器 generatoryield 的机制和 nextsend 的用法,并展示了如何用 generator 生成无限序列。

在循环中使用生成器作为迭代对象,就不用将所有需要遍历的值都全部计算出来再迭代,而是可以每迭代一次就计算一个需要遍历的值。

这种写法有以下几个好处:

  1. 节省内存资源:生成器以延迟计算的方式逐个生成数据,不会一次性生成所有数据,因此可以避免在内存中存储大量数据,从而减少内存资源的占用。
  2. 更快的计算速度:由于生成器以延迟计算的方式逐步生成数据,避免了一次性计算所有数据所带来的资源浪费,因此生成器往往比一次性生成所有数据的方式更加高效。
  3. 更灵活的逻辑处理:生成器可以动态地生成数据,并且可以支持迭代过程中的数据清洗、处理等操作,从而让代码更加灵活、简单。

Python 进阶教程系列 2:装饰器

本文是 Python 进阶教程系列 2,主要介绍了装饰器的机制和用法。

Python 是一种功能强大的编程语言,其灵活性和可扩展性使得开发者能够创造出各种强大且高效的应用程序。其中一个让 Python 如此受欢迎的特性就是装饰器(Decorators)。

装饰器是一种可以动态地修改某个类或函数的行为的函数,它们在不修改源代码的情况下为已经存在的函数或类添加额外的功能。

我对装饰器的理解是:装饰器即为“传入一个函数,传出一个被加工后的函数”的函数。

Python 进阶教程系列 1:双下划线的魔法方法

在构建大型项目时,一些进阶的 Python 开发技术能够让我们编写可复用、可拓展、更优雅、更高效的代码,使得代码清晰、整洁且便于维护。本系列笔记参考了 YouTube NeuralNine 频道Python Advanced Tutorials 系列视频,内容涵盖魔法函数、装饰器、生成器、参数解析等内容。

本文是 Python 进阶教程系列 1,主要介绍了双下划线的魔法方法的作用及示例代码,包括__init____str____len____getitem____add____call____format__ 等。

image-20230724232129477

使用 Ruff 自动检查代码错误

在编写大型项目时,一些细节代码容易影响代码的正常运行。若花费太多时间检查变量命名、导入包等细节问题,则会大幅影响工作效率和心情。

Ruff 是一个代码分析工具,即 Linter,它可以用于检查代码中的语法错误、编码规范问题、潜在的逻辑问题和代码质量问题等,可以提供实时反馈和自动修复建议。

Ruff 的优点是速度非常快,且安装和使用都非常简单。使用 Ruff 可以帮助我们自动检查代码存在的错误(如变量未定义、缺失外部依赖包等),这一切都不需要真正花时间运行代码。

Shows a bar chart with benchmark results.

Dijkstra 算法求解最短路径问题

本文使用 Python 实现了 Dijkstra 算法求解最短路径问题。在算法实现中,使用数组存储网络中各结点之间的距离,使用二叉堆存储 T 集合,并尽量使用向量化计算加快运行速度。

最终在三种网络结构下的运行时间为:

输入文件 grid_150_150 random_20000_40000 dense_1000
运行时间 302.93ms 292.14ms 135.29ms

但在最开始实现 Dijkstra 算法时,我的程序需要花 5 秒才能完成计算。经过逐步优化,运行时间可以降为 3 秒甚至 0.13 秒。把算法效率优化到极致的过程是非常有收获的,既加深了对算法本身的理解,又学习了许多优化算法的经验。

优化算法的经验

  1. 多考虑用向量化计算,尽量避免使用 for 循环。
  2. 想清楚算法的终止条件是什么。例如,在 One-to-all 问题中,可以把“遍历完T集合中的所有元素,直到 T 集合为空集”作为终止条件,也可以把“ P 集合中的元素个数等于网络中的结点个数”作为终止条件。虽然两者都能得到正确的结果,但当 P 集合中的元素个数等于网络中的结点个数时,T 集合中的元素是不需要再更新的,所以后者比前者所需要的运算次数少得多。
  3. 熟悉 NumPy 等科学计算库的实现细节。例如,在 NumPy 中,np.onesnp.empty 都可以用来创建指定形状的数组,其中 np.ones 会创建一个填充 1 的数组,而 np.empty 会在一块内存上创建一个未初始化的数组。由于 np.empty 不会进行初始化,因此生成速度要比 np.ones 更快。
  4. 使用合适的数据类型。例如,若问题中的变量可以肯定为整数,则可以考虑用 dtype=np.int32 或者 dtype=np.int16,节约内存空间。不同整数数据类型所能表示的整数范围如下:
Type Capacity
Int16 (-32,768 to +32,767)
Int32 (-2,147,483,648 to +2,147,483,647)
Int64 (-9,223,372,036,854,775,808 to +9,223,372,036,854,775,807)

Python 滚动回归

本文实现了多个资产分别在时间序列上进行滚动回归,并返回由最新系数计算得到的残差,最后将多个资产的残差结果重新聚合为多重索引的数据框。

image-20230424173801905