Scipy has an different way of handling submodules to Numpy, for example
import scipy as sp
import numpy as np
A = np.eye(4)
np.linalg.det(A)
sp.linalg.det(A)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'scipy' has no attribute 'linalg'
This is moderately annoying because of the asymmetry with respect to Numpy, but it is exactly the behaviour that the documentation describes. The proper usage according to the docs is
from scipy import linalg
import numpy as np
A = np.eye(4)
np.linalg.det(A)
linalg.det(A) # using Scipy
which works just fine.
Now, here's the weird thing
import scipy as sp
import numpy as np
from scipy.linalg import expm # extra line inserted into first example
A = np.eye(4)
np.linalg.det(A)
sp.linalg.det(A)
then the Numpy-style code works just fine. The extra line causes linalg to be added to the namespace sp, a side effect of the extra import.
I get the programming pattern I want but the third line is not easy to explain in example code.
QUESTION: why does Scipy do this? is there any more straightforward way to have it so that Scipy behaves more Numpyish?
In fact, you almost never need or to want import scipy as sp or anything like that.
There is almost nothing in the top level scipy namespace. All useful stuff is in subpackages (one exception is LowLevelCallable which is in the top-level namespace). This way, users are better off either importing from subpackages, from scipy.signal import detrend, or importing subpackages themselves (from scipy import signal; signal.detrend(...)).
As to the disparity with numpy, numpy is very much the opposite: a lot of useful stuff is in the top-level namespace, so you import it from there.
Unless you're using np.linalg, np.random, np.fft or np.testing, which are public-facing usable submodules.
Related
I'm coding in Spyder and the code runs, but every line that uses sp.___ raises a DeprecationWarning, e.g. DeprecationWarning: scipy.array is deprecated and will be removed in SciPy 2.0.0, use numpy.array instead.
Why is Spyder doing this and how do I allow me to use scipy without raising this error? Failing that, what can I do to suppress the error from popping up each time?
The code is like this:
import matplotlib.pyplot as plt,scipy as sp
import scipy.optimize as op
a=9.3779
x_in=sp.array([.095,.065,.09,.108,.125,.115,.040,.055,.055])
x=(x_in+14)
y_in=sp.array([.2,.6,.5,.4,.1,.3,-0.2,-0.4,0])
y=y_in+45
ax.plot(x_in,y_in,'ro')
plt.show()
This raises the error:
C:\Users\Shiva Pingle\Desktop\python\others\peaks.py:38: DeprecationWarning: scipy.array is deprecated and will be removed in SciPy 2.0.0, use numpy.array instead
x_in=sp.array([.095,.065,.09,.108,.125,.115,.040,.055,.055])
C:\Users\Shiva Pingle\Desktop\python\others\peaks.py:40: DeprecationWarning: scipy.array is deprecated and will be removed in SciPy 2.0.0, use numpy.array instead
y_in=sp.array([.2,.6,.5,.4,.1,.3,-0.2,-0.4,0])
Your solution in the comments will make you ignore all the deprecation warnings. This is not suggested.
You could instead import numpy as np and use the np.array().
Corrected code:
import matplotlib.pyplot as plt,scipy as sp
import scipy.optimize as op
import numpy as np # Added import of numpy
a=9.3779
x_in=np.array([.095,.065,.09,.108,.125,.115,.040,.055,.055]) # Changed sp to np
x=(x_in+14)
y_in=np.array([.2,.6,.5,.4,.1,.3,-0.2,-0.4,0]) # Changed sp to np
y=y_in+45
plt.plot(x_in,y_in,'ro') # Also changed the ax to plt
plt.show()
I couldn't find any official documentation of the fact that scipy.fft actually is a link to numpy.fft.fftpack.fft. Here is an iPython session showing the link:
In [1]: import scipy
In [2]: import numpy
In [3]: scipy.__version__
Out[3]: '0.19.0'
In [4]: numpy.__version__
Out[4]: '1.12.1'
In [5]: scipy.fft
Out[5]: <function numpy.fft.fftpack.fft>
The only mentions I could find of a scipy.fft submodule were this discussion on numpy-discussion and this discussion on SciPy's Github, both of which seem to hint at the fact that no such submodule actually existed at the time.
Yes, it's documented:
Guidelines for importing functions from Scipy
The scipy namespace itself only contains functions imported from numpy. These functions still exist for backwards compatibility, but should be imported from numpy directly.
[...]
The scipy.__init__.py file has:
from numpy import *
from numpy.random import rand, randn
from numpy.fft import fft, ifft
from numpy.lib.scimath import *
__all__ += _num.__all__
__all__ += ['randn', 'rand', 'fft', 'ifft']
I'm certainly missing something very obvious here, but why does this work:
a = [0.2635,0.654654,0.365,0.4545,1.5465,3.545]
import statsmodels.robust as rb
print rb.scale.mad(a)
0.356309343367
but this doesn't:
import statsmodels as sm
print sm.robust.scale.mad(a)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-1ce0c872b0be> in <module>()
----> 1 print statsmodels.robust.scale.mad(a)
AttributeError: 'module' object has no attribute 'robust'
Long answer see http://www.statsmodels.org/stable/importpaths.html
Statsmodels has intentionally mostly empty __init__.py but has a parallel import collection through the api.py.
The recommended import for interactive work import statsmodels.api as sm imports almost all of statsmodels, numpy, pandas and patsy, and large parts of scipy. This is slooow on cold start.
If we want to import just a specific part of statsmodels, then we don't need to import all these extras. Having empty __init__.py means that we can import just a single module (which of course imports the dependencies of that module).
e.g. from statsmodels.robust.scale import mad or
import statmodels.robust scale as smscale
smscale.mad(...)
(Small caveat: Some of the very low level imports might not remain always backwards compatible if the internal structure changes. However, the general policy is to deprecate functions over one or two releases while maintaining the old access structure.)
You can, you just have to import robust as well:
import statsmodels as sm
import statsmodels.robust
Then:
>>> sm.robust.scale.mad(a)
0.35630934336679576
robust is a subpackage of statsmodels, and importing a package does not in general automatically import subpackages (unless the package is written to do so explicitly).
I tried two different import syntaxes I thought were equivalent. Weirdness seems to ensue:
In [7]: import sympy
In [8]:sympy.physics.units.find_unit("Giga Electron Volt")
Traceback (most recent call last):
File "<ipython-input-8-8a26ac4a085a>", line 1, in <module>
sympy.physics.units.find_unit("Giga Electron Volt")
AttributeError: 'module' object has no attribute 'physics'
In [9]:import sympy.physics.units as u
In [10]:u.find_unit("coul")
Out[10]: ['coulomb', 'coulombs']
In [11]:import sympy
In [12]:sympy.physics.units.find_unit("coul")
Out[12]: ['coulomb', 'coulombs']
Take a look at the source code of sympy here: https://github.com/sympy/sympy/blob/master/sympy/init.py#L55
from .calculus import *
# Adds about .04-.05 seconds of import time
# from combinatorics import *
# This module is slow to import:
#from physics import units
from .plotting import plot, textplot, plot_backends, plot_implicit
They are not importing the physics module, because it takes obviously quite some time to load. This is why you get the error in the first try.
After loading it manually, the interpreter has it loaded and knows where it is (from your manual import). Thats why it works on the second try.
So the phenomenon is not regarded to python import functionality, but to the module initialization.
P.S.
If you uncomment the line that loads unit from the physics module, it would be
import sympy
sympy.units.find_unit("coul")
I'm using spyder and have written the following class:
class Ray:
def __init__(self, r, p, k):
if r.shape == (3,):
self.r = r
if p.shape == (3,):
self.p = p
if k.shape == (3,):
self.k = k
r = array(range(3))
p = array(range(3))
k = array(range(3))
It is stored in /home/user/workspace/spyder/project and the console working directory is that one. In the console I can run an array(range(3)) and it returns an array with values 0,1,2. However when doing
import ray
I get the following error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ray.py", line 8, in <module>
class Ray:
File "ray.py", line 20, in ray
r = array(range(3));
NameError: name 'array' is not defined
EDIT:
by default spyder has the following behaviour, don't really understand why array() works by default I thought it was only part of numpy.
import numpy as np # NumPy (multidimensional arrays, linear algebra, ...)
import scipy as sp # SciPy (signal and image processing library)
import matplotlib as mpl # Matplotlib (2D/3D plotting library)
import matplotlib.pyplot as plt # Matplotlib's pyplot: MATLAB-like syntax
from mayavi import mlab # 3D plotting functions
from pylab import * # Matplotlib's pylab interface
ion() # Turned on Matplotlib's interactive mode
Within Spyder, this intepreter also provides:
* special commands (e.g. %ls, %pwd, %clear)
* system commands, i.e. all commands starting with '!' are subprocessed
(e.g. !dir on Windows or !ls on Linux, and so on)
You need from numpy import array.
This is done for you by the Spyder console. But in a program, you must do the necessary imports; the advantage is that your program can be run by people who do not have Spyder, for instance.
I am not sure of what Spyder imports for you by default. array might be imported through from pylab import * or equivalently through from numpy import *. If you want to directly copy code from the Spyder console to a program, you might need from numpy import * or even from pylab import *. It is officially not recommended to do this in a program, though, as this pollutes the program's namespace; doing import numpy as np and then np.array(…) is customary.