The difference between np.function and function [duplicate] - python

This question already has answers here:
Why is "import *" bad?
(12 answers)
How do I import other Python files?
(23 answers)
Closed 5 years ago.
We can import numpy and use its functions directly as:
from numpy import *
a = arraay([1,2,3]) # and it works well.
Why do some people use the following method?
import numpy as np
a= np.array([1,2,3])

The difference is easy: from numpy import * imports all names from the top-level NumPy module into your current "module" (namespace). import numpy as np will just make that top-level NumPy module available if you use np.xxx.
However there is one reason why you shouldn't use from any_module import *: It may just overwrite existing names. For example NumPy has its own any, max, all and min functions, which will happily shadow the built-in Python any, max, ... functions (a very common "gotcha").
My advise: Avoid from numpy import * even if it seems like less effort than typing np. all the time!

It's a matter of neatness but also consistency: you might have multiple functions with the same name from different modules (for instance there's a function called "random" in Numpy, but also in other packages like SciPy) so it's important to denote which exact function you're using from which exact module. This link has a great explanation and makes the point about code readability as well.

Related

Find all functions/classes of a package in Python [duplicate]

This question already has answers here:
How to list all functions in a module?
(20 answers)
Closed 5 months ago.
Is there a way to retrieve all the different functions/classes of a specific package?
For example, I'd like to receive something like this for scipy:
scipy.ndimage.center_of_mass
scipy.ndimage.binary_dilation
scipy.ndimage.binary_erosion
scipy.ndimage.gaussian_filter
scipy.ndimage.filters.gaussian_filter
scipy.ndimage.filters.convolve
scipy.ndimage.sobel
scipy.ndimage.zoom
scipy.ndimage.distance_transform_edt
scipy.ndimage.filters.convolve
scipy.spatial.distance.cdist
scipy.optimize.curve_fit
scipy.signal.find_peaks
scipy.signal.correlate
scipy.signal.peak_widths
scipy.signal.find_peaks
scipy.signal.peak_widths
scipy.interpolate.LinearNDInterpolator
scipy.interpolate.interp1d
scipy.interpolate.make_interp_spline
scipy.integrate.trapz
scipy.linalg.circulant
This is just a subset of scipy, but you can get the idea. I'd like to list all the different functions/classes of that package. Is there a tool that does that maybe?
There are many ways:
dir(module)
or
from inspect import getmembers, isfunction
from somemodule import foo
print(getmembers(foo, isfunction))
but in your case, scipy contains other sub packages. To print all the contents of a package, you can use .__all__:
scipy.__all__
This produce a list of all submodules, methods, functions and attributes. It is possible to select the relevant for your according to the type (module, function or other). You just need to loop over them and check their corresponding types:
for i in scipy.__all__:
print(f"{i}: {type(getattr(scipy, i))}")
For each subpackage, you can use getmembers function from inspect to get the function and the classes of each. you can specify using is function, ismodule and ismethod what you're really looking for.
For more details, https://docs.python.org/3/library/inspect.html#inspect.getmembers
import inspect
inspect.getmembers(scipy.signal, inspect.ismodule)

Why mock patching works with random but not with np?

I have a module where a number of different functions use random numbers or random choices.
I am trying to use mock and patch to inject pre-chosen values in place of these random selections but can't understand an error I am receiving.
In the function I am testing, I use
np.random.randint
when I use the code
from unittest import mock
import random
mocked_random_int = lambda : 7
with mock.patch('np.random.randint', mocked_random_int):
I get an error message no module named np. However, numpy is imported as np and other functions are calling it just fine.
Even more perplexing if I edit the code above to remove the 'np' at the front it does what I want:
with mock.patch('random.randint', mocked_random_int):
But I want to understand why the code works without the np. Thank you!
There is a difference between a module or package name and the variable it is assigned to in any given namespace. A simple import
import numpy
tells python to check its imported module list, import numpy as necessary, and assign the module to the variable "numpy"
import numpy as np
is almost the same, except that you assign to a variable "np". Its still the same numpy package, its just that you've aliased it differently.
mock.patch will import and patch the module regardless of whether you've already imported it, but you need to give the module name, not your current module's alias to the module.

Calling numpy functions

Is it okay to call any numpy function without using the library name before the function (example: numpy.linspace())? Can we call it simply
linspace()
instead of calling
numpy.linspace()
You can import it like this
from numpy import linspace
and then use it like this
a = linspace(1, 10)
yes, its completely fine when you are importing the function separately from the numpy such as
from numpy import linespace
#you can call the function by just writing its name
result=linespace(3,50)
but the convention is to use the name alias the pakage as np
import numpy as np
#then calling the function with short name
result = np.linespace(3,50)
alias can be helpful when working with large number of libraries.and it also improves the code readability.
If you import the function from the library directly there is nothing wrong with calling said function directly.
i.e.
from numpy import linspace
# Then call linspace by itself
a = linspace(1, 10)
That being said, many find that having numpy (often shortened to np) in front of function names help improve code readability. As almost everyone does this with certain libraries (Tensorflow as tf, Numpy as np, Pandas as pd) some may view it in a poor light if you simply directly import and use the function.
I would recommend importing the library as the shortened name and then using it appropriately.
i.e.
import numpy as np
# Then call np.linspace
a = np.linspace(1, 10)

import numpy as np versus from numpy import

I have a module that heavily makes use of numpy:
from numpy import array, median, nan, percentile, roll, sqrt, sum, transpose, unique, where
Is it better practice to keep the namespace clean by using
import numpy as np
and then when I need to use array just use np.array, for e.g.?
This module also gets called repeatedly, say a few million times and keeping the namespace clean appears to add a bit of an overhead?
setup = '''import numpy as np'''
function = 'x = np.sum(np.array([1,2,3,4,5,6,7,8,9,10]))'
print(min(timeit.Timer(function, setup=setup).repeat(10, 300000)))
1.66832
setup = '''from numpy import arange, array, sum'''
function = 'x = sum(array([1,2,3,4,5,6,7,8,9,10]))'
print(min(timeit.Timer(function, setup=setup).repeat(10, 300000)))
1.65137
Why does this add more time when using np.sum vs sum?
You are right, it is better to keep the namespace clean. So I would use
import numpy as np
It keeps your code more readable, when you see a call like np.sum(array) you are reminded that you should work with an numpy array. The second reason is that many of the numpy functions have identical names as functions in other modules like scipy... If you use both its always clear which one you are using.
As you you can see in the test you made, the performance difference is there and if you really need the performance you could do it the other way.
The difference in performance is that in the case of a specific function import, you are referencing the function in the numpy module at the beginning of the script.
In the case of the general module import you import only the reference to the module and python needs to resolve/find the function that you are using in that module at every call.
You could have the best of both worlds (faster name resolution, and non-shadowing), if you're ok with defining your own aliasing (subject to your team conventions, of course):
import numpy as np
(np_sum, np_min, np_arange) = (np.sum, np.min, np.arange)
x = np_arange(24)
print (np_sum(x))
Alternative syntax to define your aliases:
from numpy import \
arange as np_arange, \
sum as np_sum, \
min as np_min

Use Function Without Calling Module [duplicate]

This question already has an answer here:
Is there a way to bypass the namespace/module name in Python?
(1 answer)
Closed last month.
I am using Canopy with the Jupyter notebook. I was wondering if there was a way to use function from a module without having to call the module. For example if I have
import numpy as np
print np.sin(2)
I would want to be able to just type
print sin(2)
The first thing that comes to mind is to add the numpy functions into whatever function library that Python is using. But I was wondering if this is feasible and, if so, how I could go about doing it. Note that I want to import all functions, not just a select few.
You can import specific objects from a module. Try:
from numpy import sin
print sin(2)
To import all objects from a module into the global namespace you can use import *.
from numpy import *
print sin(2)
But this is not recommended because you can easily end up with name clashes, e.g. if two modules define a function named sin which version of sin should be called?
>>> import math
>>> import numpy
>>> math.sin
<built-in function sin>
>>> numpy.sin
<ufunc 'sin'>
>>> from math import *
>>> sin
<built-in function sin>
>>> from numpy import *
>>> sin
<ufunc 'sin'>
You can see here that the second import from numpy replaced sin in the global namespace.
For this reason it is best to import the specific objects that you need if there are only a few, otherwise just import the module and use the module name as a prefix (as per your first example). In my example if you wanted to use both math.sin and nump.sin you would either need to import the modules only and prefix using the module name, or import the functions and rename them like this:
from numpy import sin as np_sin
from math import sin
from numpy import sin
print sin(2)
https://docs.python.org/2/tutorial/modules.html read this in details

Categories