SciPy路线图详细说明#
本路线图主要旨在从新功能、错误修复等方面为每个SciPy子模块提供一个高层次的概述。除了重要的“日常业务”更改外,它还包含了一些主要新功能的想法——这些想法被标记为“主要新功能”,并且预计需要投入大量的专门精力。本路线图中未提及的内容并不一定不重要或不在范围之内,但是我们(SciPy开发人员)希望为我们的用户和贡献者提供一个清晰的图景,了解SciPy的发展方向以及最需要帮助的地方。
注意
这是详细的路线图。一个非常高层次的概述,只包含最重要的想法,请参见SciPy路线图。
通用#
本路线图将随着SciPy一起发展。更新可以作为拉取请求提交。对于大型或破坏性的更改,您可能需要先在scipy-dev论坛上讨论。
API更改#
一般来说,我们希望发展API以尽可能地消除已知的缺陷,但是尽可能地不破坏向后兼容性。
测试覆盖率#
过去几年添加的代码的测试覆盖率相当不错,我们希望所有新添加的代码的覆盖率都很高。但是,仍有大量的旧代码覆盖率很差。将这些代码提升到目前的标准可能不现实,但我们应该堵住最大的漏洞。
除了覆盖率外,还有正确性的问题——较旧的代码可能有一些测试提供了不错的语句覆盖率,但这并不一定说明代码是否按预期工作。因此,需要对代码的某些部分(特别是stats
、signal
和ndimage
)进行代码审查。
文档#
文档的状况良好。继续扩展当前的文档字符串——添加示例、参考资料和更详细的说明。大多数模块在参考指南中也都有一个教程,这是一个很好的入门,但是有一些教程缺失或不完整——这应该得到解决。
基准测试#
基于asv
的基准测试系统状态良好。添加新的基准测试非常容易,但是运行基准测试并不直观。提高这方面的易用性是优先事项。
Cython的使用#
Cython的旧语法(用于使用NumPy数组)应该被删除,并用Cython内存视图代替。
从Cython代码构建的扩展的二进制文件大小很大,编译时间很长。我们应该尽可能地合并扩展模块(例如,stats._boost
现在包含许多扩展模块),并将Cython的使用限制在最适合的地方。请注意,scipy.special
正在进行Cython到C++的转换。
Pythran的使用#
Pythran仍然是一个可选的构建依赖项,可以通过-Duse-pythran=false
禁用。目标是将其设置为硬依赖项——为此,必须明确维护负担足够低。
使用久经考验的Fortran库#
SciPy的成功在很大程度上归功于依赖于封装成熟的Fortran库(QUADPACK、FITPACK、ODRPACK、ODEPACK等)。其中一些库维护得很好,而另一些则维护得不太好。我们应该根据维护工作量、功能以及(可能是部分)替代方案的存在来审计我们对这些库的使用情况,包括SciPy内部的那些。
持续集成#
持续集成目前涵盖了32/64位Windows、x86-64/arm上的macOS、x86上的32/64位Linux以及aarch64上的Linux——以及我们依赖项的各种版本和构建发布质量的轮子。由于要支持大量的配置,并且一些CI作业需要大修,CI的可靠性最近(2023年上半年)并不理想。我们旨在通过删除删除distutils构建系统后剩余的distutils构建作业,并使CI作业中的配置集更加正交来减少构建时间。
二进制文件大小#
SciPy二进制文件相当大(例如,1.7.3的解压缩的manylinux wheel在PyPI上为39 MB,安装后为122 MB),这可能会造成问题——例如,在AWS Lambda中使用时,AWS Lambda有250 MB的大小限制。我们的目标是尽可能地保持二进制文件大小;添加新的编译扩展时,需要进行检查。multibuild
中的调试符号剥离也许可以改进(参见这个问题)。应该努力尽可能地精简,不要添加新的大型文件。在未来,正在考虑(非常谨慎地)并且可能有所帮助的事情是,将捆绑的` libopenblas
分开,并删除对long double
的支持。
模块#
cluster#
dendrogram
需要重写,它有许多难以修复的开放问题和功能请求。
constants#
这个模块基本上已经完成,维护量低,没有开放问题。
fft#
这个模块状况良好。
integrate#
对于ODE求解器来说是必要的
文档很糟糕,需要修复
在SciPy 1.0.0中添加了一个新的ODE求解器接口(
solve_ivp
)。在未来,我们可以考虑(软)弃用旧的API。
数值积分函数状况良好。可以添加对积分复值函数和积分多个区间的支持(参见gh-3325)。
interpolate#
样条拟合:我们需要具有更好用户控制的样条拟合例程。这包括
用户可选择的平滑标准替代方案(手动、交叉验证等);gh-16653在这方面取得了进展;
用于节点放置的几种策略,包括手动和自动策略(使用Dierckx、de Boor的算法,可能还有其他算法)。
一旦我们拥有一个功能齐全的集合,我们就可以开始长时间审视久经考验的FITPACK Fortran库的未来,目前这是在SciPy中构建平滑样条的唯一方法。
可扩展性和性能:对于基于FITPACK的功能,数据大小受32位Fortran整数大小限制(对于非ILP64构建)。对于N维散点插值器(基于QHull)和N维规则网格插值器,我们需要检查大型数据集上的性能,并在性能不足的情况下进行改进(gh-16483在这方面取得了进展)。
新功能的想法:可以添加NURBS支持。
io#
wavfile
将支持PCM float,对于其他任何内容,请使用
audiolab
或其他专用库。如果数据无法理解,则引发错误而不是警告。
其他子模块(matlab、netcdf、idl、harwell-boeing、arff、matrix market)状况良好。
linalg#
scipy.linalg
状况良好。
需要
减少与
numpy.linalg
函数的重复,使API保持一致。get_lapack_funcs
应该始终使用flapack
封装更多LAPACK函数
LU分解的函数太多了,删除一个
新功能的想法
在Cython BLAS和LAPACK中添加类型泛型包装器
将许多线性代数例程转换为gufuncs
BLAS和LAPACK
scipy.linalg
中对BLAS和LAPACK的Python和Cython接口是SciPy提供的最重要的功能之一。总的来说,scipy.linalg
状况良好,但是我们可以进行一些改进
库支持。我们发布的轮子现在附带OpenBLAS,这是目前唯一可行的性能良好的选项(ATLAS太慢,MKL由于许可问题不能作为默认选项,Accelerate支持被取消,因为Apple不再更新Accelerate)。但是,OpenBLAS并不稳定,有时它的版本会导致问题,并且在使用线程时存在问题(目前是使用SciPy与PyPy3的唯一问题)。我们至少需要更好地支持调试OpenBLAS问题,以及关于如何使用它构建SciPy的更详细的文档。一个选择是使用BLIS作为BLAS接口(参见numpy gh-7372)。
对较新LAPACK功能的支持。在SciPy 1.2.0中,我们将LAPACK的最低支持版本提高到3.4.0。现在我们已经删除了Python 2.7,我们可以进一步提高该版本(MKL+Python 2.7是之前>3.4.0的阻碍因素),并开始添加对LAPACK中新功能的支持。
misc#
scipy.misc
将作为一个公共模块被删除。它的大多数函数已被移至另一个子模块或被弃用。剩下的几个函数
derivative
,central_diff_weight
:移除,可能用更广泛的数值微分功能来替换。ascent
,face
,electrocardiogram
:移除或移动到适当的子包(例如,scipy.ndimage
,scipy.signal
)。
ndimage#
底层ndimage
是一个强大的插值引擎。用户期望两种模型之一:具有 (1, 1)
元素且中心为 (0.5, 0.5)
的像素模型,或数据点模型,其中值在网格上的点定义。随着时间的推移,我们越来越相信数据点模型定义更清晰,更容易实现,但应在文档中清楚地传达这一点。
更重要的是,SciPy 实现此数据点模型的一种变体,其中在周期性包装模式下,轴的任意两个极端的数据点共享一个空间位置。例如,在 1D 数组中,您将拥有 x[0]
和 x[-1]
共置。然而,一个非常常见的用例是信号是周期性的,沿轴的第一个元素和最后一个元素之间具有相等的间距(而不是零间距)。针对此用例的包装模式已在 gh-8537 中添加,接下来插值例程应更新为使用这些模式。这应该解决一些问题,包括 gh-1323、gh-1903、gh-2045 和 gh-2640。
形态学接口需要标准化
二值膨胀/腐蚀/开运算/闭运算采用“结构”参数,而其灰度等效项采用大小(必须是元组,而不是标量)、足迹或结构。
标量对于大小应该是可以接受的,等效于为每个轴提供相同的值。
对于二值膨胀/腐蚀/开运算/闭运算,结构元素是可选的,而对于灰度是强制性的。灰度形态学操作应获得相同的默认值。
其他滤波器也应在可能的情况下取该默认值。
odr#
该模块处于合理状态,尽管它可以使用更多维护。这里没有重大计划或愿望。
optimize#
总的来说,该模块处于良好状态。1.2.0 中添加了两个好的全局优化器;大规模优化器仍然是一个可以填补的空白。其他需要的东西
关于
linprog
中附加功能(例如整数约束)的许多想法,请参阅 gh-9269。向基准套件添加功能,以便更容易比较结果(例如,使用摘要图)。
在文档中弃用
fmin_*
函数,minimize
是首选。scipy.optimize
有一套广泛的基准,用于测试全局优化器的准确性和速度。这使得能够添加新的优化器(shgo
和dual_annealing
),其性能明显优于现有优化器。然而,optimize
基准系统本身很慢且难以使用;我们需要使其更快,并通过绘制性能曲线来更轻松地比较优化器的性能。
signal#
卷积和相关性:(相关函数是 convolve、correlate、fftconvolve、convolve2d、correlate2d 和 sepfir2d。)消除与 ndimage(以及其他地方)的重叠。从 numpy
、scipy.signal
和 scipy.ndimage
(以及我们找到它们的任何其他地方),选择 1-D、2-D 和 n-d 卷积和相关性的“最佳类”,将实现放在某个地方,并在整个 SciPy 中一致地使用它。
B 样条:(相关函数是 gauss_spline、cspline1d、qspline1d、cspline2d、qspline2d、cspline1d_eval 和 spline_filter。)将好的东西移到 interpolate(通过适当的 API 更改来匹配 interpolate 中的执行方式),并消除任何重复。
滤波器设计:合并 firwin 和 firwin2,以便可以移除 firwin2。
连续时间线性系统:进一步提高 ltisys
的性能(在不同表示之间进行更少的内部转换)。填补 lti 系统转换函数中的空白。
二阶截面:使 SOS 滤波与现有方法一样强大。这包括 ltisys 对象、lfiltic 等效项以及在其他滤波器表示之间进行数值稳定的转换。对于其数值稳定性,SOS 滤波器可以被视为 ltisys 对象的默认滤波方法。
小波:现在的小波没有多大意义。目前只有连续小波 - 决定是完全重写还是移除它们。离散小波变换超出了范围(PyWavelets 对它们做了很好的工作)。
sparse#
稀疏矩阵格式在很大程度上功能完备,但主要问题是它们的行为类似于 numpy.matrix
(这将在 NumPy 中的某个时候被弃用)。
我们想要的是行为类似于 numpy.ndarray
的稀疏数组。SciPy 1.8.0
中添加了对新类集(csr_array
等)的初步支持,并在 1.12.0
中添加了数组的构造函数时稳定下来。预计在 1.13.0
中支持 1-D 数组。
支持稀疏数组的下一步
- 将稀疏数组 API 扩展到 1-D 数组。
支持 COO、CSR 和 DOK 格式。
CSR 1D 支持 min-max、索引、算术。
帮助其他库从稀疏矩阵转换为稀疏数组。创建转换指南和有用的脚本以标记需要进一步检查的代码。NetworkX、scikit-learn 和 scikit-image 正在进行或已完成转换为稀疏数组。
在稀疏数组代码成熟后(大约 1 个发布周期?),添加弃用稀疏矩阵的警告。
与 NumPy 协作弃用/移除
numpy.matrix
。弃用然后删除稀疏矩阵,转而使用稀疏数组。
- 开始构造函数名称的 API 转换(
diags
、block
等)。 注意:总体而言,构造函数经历了两次名称转换。一次是将矩阵创建移到用于数组创建的新函数(即
eye
->eye_array
)。然后第二次转换是更改名称以匹配array_api
名称(即eye_array
到eye
),在移除稀疏矩阵之后。我们将在很长一段时间内保留*_array
版本作为(可能隐藏的)别名。
- 开始构造函数名称的 API 转换(
添加与
array_api
名称匹配的构造函数名称。弃用转换构造函数名称。
正在 pydata/sparse 中研究一个替代方案(更雄心勃勃,目前还不清楚是否会实现)。为了支持这项工作,我们的目标是支持所有接受稀疏数组的函数中的 PyData Sparse。在 scipy.sparse.linalg
和 scipy.sparse.csgraph
中支持 pydata/sparse
基本上已经完成。
关于不同的稀疏矩阵格式:有很多。这些应该保留,但改进/优化应该投入 CSR/CSC,它们是首选的格式。LIL 可能是一个例外,它本质上是低效的。如果 DOK 被扩展为支持 LIL 目前提供的所有操作,它可以被删除。
sparse.csgraph#
这个模块状况良好。
sparse.linalg#
对于 _arpack
和 lobpcg
,存在大量未解决的问题。_propack
是 1.8.0 中的新功能,待定其可靠性。
_isolve
:
回调关键字不一致
tol 关键字已损坏,应为相对容差
Fortran 代码不可重入(但我们不求解,也许可以从 PyKrilov 重用)
_dsolve
:
添加许可证兼容的稀疏 Cholesky 或不完全 Cholesky
添加许可证兼容的稀疏 QR
改进 SuiteSparse UMFPACK 的接口
添加 SuiteSparse CHOLMOD 和 SPQR 的接口
spatial#
QHull 包装器状态良好,KDTree
也是如此。
正在对 spatial.distance
度量进行 C++ 重写 - 这将提高性能,使行为(例如,对于各种非 float64 输入数据类型)更加一致,并解决一些度量数学实现的定义中存在的剩余问题。
special#
虽然仍然有很多函数需要提高精度,但可能唯一的问题是超几何函数、抛物柱面函数和球状波函数。处理此问题的三种可能方法
获得良好的双精度实现。这对抛物柱面函数来说是可以实现的(正在进行中)。我认为超几何函数也是可以实现的,尽管可能来不及了。对于球状波函数,目前没有理论可以做到这一点。
移植 Boost 的任意精度库,并在幕后使用它来获得双精度精度。这可能需要作为对超几何函数的权宜之计;使用任意精度的想法之前由 @nmayorov 和在 gh-5349 中提出。可能需要用于球状波函数,这可以重复使用:radelman/scattering。
在文档中添加关于现有实现局限性的明确警告。
统计#
scipy.stats
子包旨在提供基础统计方法,这些方法可能在标准统计学教科书中有所涉及,例如 Johnson 的“Miller & Freund 的工程师概率与统计”,Sokal & Rohlf 的“生物测量学”或 Zar 的“生物统计学分析”。它不试图复制下游包(例如 StatsModels、LinearModels、PyMC3)的先进功能;相反,它可以提供一个坚实的基础,这些包可以建立在其之上。(注意,这些只是粗略的指南,不是严格的规则。“高级”是一个定义不明确且主观的术语,SciPy 中也可能包含“高级”方法,尤其是在没有其他广泛使用且支持良好的包涵盖该主题的情况下。另请注意,与下游项目的一些重复是不可避免的,也不一定是件坏事。)
除了在 SciPy 路线图 中描述的项目之外,以下改进将有助于 SciPy 更好地发挥这一作用。
添加基础且广泛使用的假设检验,例如
事后检验(例如 Dunnett 检验)
各种类型的方差分析(ANOVA)
双因素 ANOVA(单次重复、均匀重复次数、可变重复次数)
多因素 ANOVA(即泛化双因素 ANOVA)
嵌套 ANOVA
协方差分析(ANCOVA)
此外,还提供用于实现假设检验的基础设施。
添加用于元分析的其他工具
添加用于生存分析的工具
加快分布的随机变量采样(方法
rvs
),在适当情况下利用scipy.stats.sampling
扩展 QMC 功能和性能
增强连续概率分布的 fit 方法
扩展拟合选项以包括
最大乘积间距
L 矩 / 概率加权矩方法
在结果中包含拟合优度度量
处理删失数据(例如,合并 gh-13699)
实现其他广泛使用的连续和离散概率分布,例如混合分布。
改进 SciPy 概率分布提供的核心计算,使其能够稳健地处理各种参数值。具体而言,用 Boost 实现替换
scipy.special
中使用的 Fortran 库 CDFLIB 中的许多 PDF 和 CDF 方法,如 gh-13328 所示。
此外,我们应该
继续努力使
stats
和stats.mstats
的函数签名更加一致,并添加测试以确保这种情况依然如此。改进统计检验:为检验统计量返回置信区间,并在计算上可行的情况下实施精确 p 值计算 - 考虑可能存在的联系。