SciPy似乎在它自己的命名空间中提供了NumPy的大部分(但不是所有[1])函数。换句话说,如果有一个名为numpy的函数。Foo,几乎可以肯定有一个sciy。Foo。大多数情况下,两者看起来完全相同,甚至经常指向相同的函数对象。
有时候,它们是不同的。举一个最近出现的例子:
numpy。log10是一个返回负参数nan的ufunc;
scipy。Log10返回负参数的复杂值,并且看起来不是一个ufunc。
对于log、log2和logn也是如此,但对于log1p[2]则不然。
另一方面,numpy。Exp和scipy。Exp似乎是同一个ufunc的不同名称。scipy也是如此。Log1p和numpy.log1p。
另一个例子是numpy.linalg.solve vs scipy.linalg.solve。它们很相似,但后者比前者提供了一些额外的功能。
为什么会出现明显的重复?如果这意味着将numpy大量导入到scipy名称空间中,那么为什么会出现行为上的细微差异和缺少函数呢?是否有一些总体逻辑可以帮助理清混乱?
[1] numpy。分钟,numpy。马克斯,numpy。Abs和其他一些名称在scipy名称空间中没有对应的名称。
[2]使用NumPy 1.5.1和SciPy 0.9.0rc2测试。
除了SciPy FAQ中描述的复制主要是为了向后兼容外,NumPy文档中也进一步澄清了这一点
可选的scipy加速例程(numpy.dual)
可由Scipy加速的函数的别名。
可以构建SciPy以使用加速或改进的库
FFTs,线性代数和特殊函数。这个模块允许
开发人员透明地支持这些加速功能时
SciPy是可用的,但仍然支持只安装了SciPy的用户
NumPy。
为了简单起见,这些是:
线性代数
FFT
一类改进的0阶贝塞尔函数
此外,从SciPy教程:
SciPy的顶层还包含NumPy和
numpy.lib.scimath。但是,最好直接从
而是NumPy模块。
因此,对于新的应用程序,您应该更喜欢使用在SciPy顶层复制的NumPy版本的数组操作。对于上面列出的域,您应该选择SciPy中的域,并在必要时检查NumPy中的向后兼容性。
根据我个人的经验,我使用的大多数数组函数都存在于NumPy的顶层(random除外)。然而,所有特定于领域的例程都存在于SciPy的子包中,因此我很少使用来自SciPy顶层的任何东西。
除了SciPy FAQ中描述的复制主要是为了向后兼容外,NumPy文档中也进一步澄清了这一点
可选的scipy加速例程(numpy.dual)
可由Scipy加速的函数的别名。
可以构建SciPy以使用加速或改进的库
FFTs,线性代数和特殊函数。这个模块允许
开发人员透明地支持这些加速功能时
SciPy是可用的,但仍然支持只安装了SciPy的用户
NumPy。
为了简单起见,这些是:
线性代数
FFT
一类改进的0阶贝塞尔函数
此外,从SciPy教程:
SciPy的顶层还包含NumPy和
numpy.lib.scimath。但是,最好直接从
而是NumPy模块。
因此,对于新的应用程序,您应该更喜欢使用在SciPy顶层复制的NumPy版本的数组操作。对于上面列出的域,您应该选择SciPy中的域,并在必要时检查NumPy中的向后兼容性。
根据我个人的经验,我使用的大多数数组函数都存在于NumPy的顶层(random除外)。然而,所有特定于领域的例程都存在于SciPy的子包中,因此我很少使用来自SciPy顶层的任何东西。
上次检查时,scipy __init__方法执行了一个
from numpy import *
以便在导入scipy模块时将整个numpy名称空间包含到scipy中。
您描述的log10行为很有趣,因为两个版本都来自numpy。一个是ufunc,另一个是numpy。自由的功能。为什么scipy更喜欢库函数而不是ufunc,我不知道在我的头顶上。
编辑:事实上,我可以回答log10的问题。在scipy __init__方法中,我看到了以下内容:
# Import numpy symbols to scipy name space
import numpy as _num
from numpy import oldnumeric
from numpy import *
from numpy.random import rand, randn
from numpy.fft import fft, ifft
from numpy.lib.scimath import *
在scipy中获得的log10函数来自numpy.lib.scimath。看看这段代码,它说:
"""
Wrapper functions to more user-friendly calling of certain math functions
whose output data-type is different than the input data-type in certain
domains of the input.
For example, for functions like log() with branch cuts, the versions in this
module provide the mathematically valid answers in the complex plane:
>>> import math
>>> from numpy.lib import scimath
>>> scimath.log(-math.exp(1)) == (1+1j*math.pi)
True
Similarly, sqrt(), other base logarithms, power() and trig functions are
correctly handled. See their respective docstrings for specific examples.
"""
该模块似乎覆盖了sqrt, log, log2, logn, log10, power, arccos, arcsin和arctanh的基本numpy ufuncs。这就解释了你所看到的行为。这样做的潜在设计原因可能隐藏在某个邮件列表帖子中。