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测试。


当前回答

来自维基百科(http://en.wikipedia.org/wiki/NumPy#History):

数字代码被用来制造 它更易于维护和灵活 足以实现新功能 Numarray。这个新项目是 SciPy。避免安装整体 来获取一个数组对象, 这个新包裹被分开了 叫NumPy。

Scipy依赖于numpy,为了方便起见,它将许多numpy函数导入到它的命名空间中。

其他回答

选自“数量经济学”讲座

SciPy是一个包,它包含各种构建在NumPy之上的工具,使用NumPy的数组数据类型和相关功能

事实上,当我们导入SciPy时,我们也得到了NumPy,这可以从SciPy初始化文件中看到

# Import numpy symbols to scipy name space
import numpy as _num
linalg = None
from numpy import *
from numpy.random import rand, randn
from numpy.fft import fft, ifft
from numpy.lib.scimath import *

__all__  = []
__all__ += _num.__all__
__all__ += ['randn', 'rand', 'fft', 'ifft']

del _num
# Remove the linalg imported from numpy so that the scipy.linalg package can be
# imported.
del linalg
__all__.remove('linalg')

但是,显式地使用NumPy功能是更常见和更好的实践

import numpy as np

a = np.identity(3)

SciPy中有用的是其子包中的功能吗

scipy。优化,scipy,整合,scipy。统计数据等。

来自维基百科(http://en.wikipedia.org/wiki/NumPy#History):

数字代码被用来制造 它更易于维护和灵活 足以实现新功能 Numarray。这个新项目是 SciPy。避免安装整体 来获取一个数组对象, 这个新包裹被分开了 叫NumPy。

Scipy依赖于numpy,为了方便起见,它将许多numpy函数导入到它的命名空间中。

除了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参考指南:

…所有Numpy函数都有 被纳入scipy 命名空间,所有这些 函数不需要 另外导入Numpy。

这样做的目的是让用户不必知道scipy和numpy名称空间之间的区别,不过显然您已经发现了一个例外。

在SciPy文档介绍的末尾有一个简短的注释:

另一个有用的命令是source。当给出一个用Python编写的函数作为参数时,它会打印出该函数的源代码列表。这对于学习算法或准确理解函数是什么很有帮助 处理它的参数。此外,不要忘记Python命令dir 用于查看模块或包的名称空间。

我认为这将允许对所涉及的所有包有足够知识的人准确地区分一些scipy和numpy函数之间的差异(这对我回答log10问题完全没有帮助)。我肯定没有这方面的知识,但来源确实表明scipy.linalg.solve和numpy.linalg.solve以不同的方式与lapack交互;

Python 2.4.3 (#1, May  5 2011, 18:44:23) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
>>> import scipy
>>> import scipy.linalg
>>> import numpy
>>> scipy.source(scipy.linalg.solve)
In file: /usr/lib64/python2.4/site-packages/scipy/linalg/basic.py

def solve(a, b, sym_pos=0, lower=0, overwrite_a=0, overwrite_b=0,
          debug = 0):
    """ solve(a, b, sym_pos=0, lower=0, overwrite_a=0, overwrite_b=0) -> x

    Solve a linear system of equations a * x = b for x.

    Inputs:

      a -- An N x N matrix.
      b -- An N x nrhs matrix or N vector.
      sym_pos -- Assume a is symmetric and positive definite.
      lower -- Assume a is lower triangular, otherwise upper one.
               Only used if sym_pos is true.
      overwrite_y - Discard data in y, where y is a or b.

    Outputs:

      x -- The solution to the system a * x = b
    """
    a1, b1 = map(asarray_chkfinite,(a,b))
    if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
        raise ValueError, 'expected square matrix'
    if a1.shape[0] != b1.shape[0]:
        raise ValueError, 'incompatible dimensions'
    overwrite_a = overwrite_a or (a1 is not a and not hasattr(a,'__array__'))
    overwrite_b = overwrite_b or (b1 is not b and not hasattr(b,'__array__'))
    if debug:
        print 'solve:overwrite_a=',overwrite_a
        print 'solve:overwrite_b=',overwrite_b
    if sym_pos:
        posv, = get_lapack_funcs(('posv',),(a1,b1))
        c,x,info = posv(a1,b1,
                        lower = lower,
                        overwrite_a=overwrite_a,
                        overwrite_b=overwrite_b)
    else:
        gesv, = get_lapack_funcs(('gesv',),(a1,b1))
        lu,piv,x,info = gesv(a1,b1,
                             overwrite_a=overwrite_a,
                             overwrite_b=overwrite_b)

    if info==0:
        return x
    if info>0:
        raise LinAlgError, "singular matrix"
    raise ValueError,\
          'illegal value in %-th argument of internal gesv|posv'%(-info)

>>> scipy.source(numpy.linalg.solve)
In file: /usr/lib64/python2.4/site-packages/numpy/linalg/linalg.py

def solve(a, b):
    """
    Solve the equation ``a x = b`` for ``x``.

    Parameters
    ----------
    a : array_like, shape (M, M)
        Input equation coefficients.
    b : array_like, shape (M,)
        Equation target values.

    Returns
    -------
    x : array, shape (M,)

    Raises
    ------
    LinAlgError
        If `a` is singular or not square.

    Examples
    --------
    Solve the system of equations ``3 * x0 + x1 = 9`` and ``x0 + 2 * x1 = 8``:

    >>> a = np.array([[3,1], [1,2]])
    >>> b = np.array([9,8])
    >>> x = np.linalg.solve(a, b)
    >>> x
    array([ 2.,  3.])

    Check that the solution is correct:

    >>> (np.dot(a, x) == b).all()
    True

    """
    a, _ = _makearray(a)
    b, wrap = _makearray(b)
    one_eq = len(b.shape) == 1
    if one_eq:
        b = b[:, newaxis]
    _assertRank2(a, b)
    _assertSquareness(a)
    n_eq = a.shape[0]
    n_rhs = b.shape[1]
    if n_eq != b.shape[0]:
        raise LinAlgError, 'Incompatible dimensions'
    t, result_t = _commonType(a, b)
#    lapack_routine = _findLapackRoutine('gesv', t)
    if isComplexType(t):
        lapack_routine = lapack_lite.zgesv
    else:
        lapack_routine = lapack_lite.dgesv
    a, b = _fastCopyAndTranspose(t, a, b)
    pivots = zeros(n_eq, fortran_int)
    results = lapack_routine(n_eq, n_rhs, a, n_eq, pivots, b, n_eq, 0)
    if results['info'] > 0:
        raise LinAlgError, 'Singular matrix'
    if one_eq:
        return wrap(b.ravel().astype(result_t))
    else:
        return wrap(b.transpose().astype(result_t))

这也是我的第一个帖子,所以如果我应该改变什么,请告诉我。