# Relationship between SciPy and NumPy

Last time I checked it, the scipy `__init__`

method executes a

`from numpy import *`

so that the whole numpy namespace is included into scipy when the scipy module is imported.

The `log10`

behavior you are describing is interesting, because *both* versions are coming from numpy. One is a `ufunc`

, the other is a `numpy.lib`

function. Why scipy is preferring the library function over the `ufunc`

, I don't know off the top of my head.

EDIT: In fact, I can answer the `log10`

question. Looking in the scipy `__init__`

method I see this:

`# Import numpy symbols to scipy name spaceimport numpy as _numfrom numpy import oldnumericfrom numpy import *from numpy.random import rand, randnfrom numpy.fft import fft, ifftfrom numpy.lib.scimath import *`

The `log10`

function you get in scipy comes from `numpy.lib.scimath`

. Looking at that code, it says:

`"""Wrapper functions to more user-friendly calling of certain math functionswhose output data-type is different than the input data-type in certaindomains of the input.For example, for functions like log() with branch cuts, the versions in thismodule 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)TrueSimilarly, sqrt(), other base logarithms, power() and trig functions arecorrectly handled. See their respective docstrings for specific examples."""`

It seems that module overlays the base numpy ufuncs for `sqrt`

, `log`

, `log2`

, `logn`

, `log10`

, `power`

, `arccos`

, `arcsin`

, and `arctanh`

. That explains the behavior you are seeing. The underlying design reason why it is done like that is probably buried in a mailing list post somewhere.

From the SciPy Reference Guide:

... all of the Numpy functions have been subsumed into the

`scipy`

namespace so that all of those functions are available without additionally importing Numpy.

The intention is for users not to have to know the distinction between the `scipy`

and `numpy`

namespaces, though apparently you've found an exception.

It seems from the SciPy FAQ that some functions from NumPy are here for historical reasons while it shouldonly be in SciPy:

## What is the difference between NumPy and SciPy?

In an ideal world, NumPy would contain nothing but the array data type and the most basic operations: indexing, sorting, reshaping, basic elementwise functions, et cetera. All numerical code would reside in SciPy. However, one of NumPy’s important goals is compatibility, so NumPy tries to retain all features supported by either of its predecessors. Thus NumPy contains some linear algebra functions, even though these more properly belong in SciPy. In any case, SciPy contains more fully-featured versions of the linear algebra modules, as well as many other numerical algorithms. If you are doing scientific computing with python, you should probably install both NumPy and SciPy. Most new features belong in SciPy rather than NumPy.

That explains why `scipy.linalg.solve`

offers some additional features over `numpy.linalg.solve`

.

I did not see the answer of SethMMorton to the related question