主要的困难(性能方面)在于混合使用 Python 对象和 numpy 数组。 我们马上会深入分析这个问题。 值得注意的是,对于这个玩具库来说,把部分 / 所有内容转换为 向量化 的 numpy 或许是可行的,但对于真正的库来说,这几乎是不可能的,因为这会使代码的可读性和可修改性大大降低,并且收益非常有限(这里有一个部分向量化的...
也许大多数库的作者都可以将数值计算外包给NumPy或SciPy。而在确实需要时,他们也可以学一点C。 然而,情况并不是那么理想。尽管将一些任务外包给NumPy、SciPy等库确实很方便,但我们不得不向量化每个函数,而且还不能使用for循环写代码,这很痛苦。担心某些操作会被全局解释器锁(GIL)阻塞也很令人头疼,还有其他各种问题。...
真正的类可能具有额外复杂的内容,比如merge方法使用了scipy.spatial中的ConvexHull方法。 为了减少开销(并限制在这篇已经很长的文章的范围内),我们只会将Polygon类的核心功能用Rust实现,然后以Python子类的形式去实现API的其余部分。 我们的结构体struct是这样的: // `Array1` is a 1d array, and the `numpy` c...
也许大多数库的作者都可以将数值计算外包给NumPy或SciPy。而在确实需要时,他们也可以学一点C。 然而,情况并不是那么理想。尽管将一些任务外包给NumPy、SciPy等库确实很方便,但我们不得不向量化每个函数,而且还不能使用for循环写代码,这很痛苦。担心某些操作会被全局解释器锁(GIL)阻塞也很令人头疼,还有其他各种问题。...
我们可以利用 PyO3 来转换 numpy 数组: 现在point 变成了 ArrayView1,我们可以直接使用了。例如: 接下来,我们需要获取每个多边形的中心,然后将其转换成 ArrayView1。 虽然信息量有点大,但总的来说,结果就是逐行转换原来的代码: 对比一下原来的代码:
于是我们看到 NumPy(1995/2006)、SciPy(2001)、Pandas(2008)和Scikit-learn(2007)鱼贯入场。如果没有这样一个用于机器学习和科学计算的、高质量且覆盖全面的工具包,Python 就不会取得今天的地位。 然而,如果你深入背后探究一番,就会发现那里没有多少 Python 的位置:你正在使用 Python 来编排和利用一个 C 和 C++ ...
import numpy as np from dataclasses import dataclass from functools import cached_property Point = np.array @dataclass class Polygon: x: np.array y: np.array @cached_property def center(self) -> Point: ... def area(self) -> float: ... ...
实际的类可能有其他复杂的东西,比如 merge 方法——使用了 scipy.spatial 中的 ConvexHull。 为了降低成本,我们只将 Polygon 的“核心”功能移至 Rust,然后从 Python 中继承该类来实现 API 的其余部分。 我们的 struct 如下所示: // `Array1` is a 1d array, and the `numpy` crate will play nicely wit...
我们还学习了ndarray生态中随机和统计相关的包,这些包一定程度上提供了scipy的相关功能。 其实ndarray的功能远远不止这些,基本上numpy有的功能ndarray都有对应的实现。这篇文章详细对比了ndarray 和numpy的函数功能,熟悉numpy的同学可以对比着学ndarray,效率会非常高。后面我也会专门做一篇numpy和ndarray方法的详细对比。
然而,情况并不是那么理想。尽管将一些任务外包给NumPy、SciPy等库确实很方便,但我们不得不向量化每个函数,而且还不能使用for循环写代码,这很痛苦。担心某些操作会被全局解释器锁(GIL)阻塞也很令人头疼,还有其他各种问题。并非你想做的一切都能轻松地找到现有库。