import numpy as np versus from numpy import - python

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

Related

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)

Apply math.erf to an array

I am using math.erf to find the error function of each element in an array.
# Import the erf function from the math library
from math import erf
# Import the numpy library to represent the input data
import numpy as np
# Create a dummy np.array
dummy_array = np.arange(20)
# Apply the erf function to the array to calculate the error function of each element
erf_array = erf(dummy_array)
I am getting an error as I cannot apply this whole function to an array. Is there a way to apply the error function to the whole array (vectorised approach) without looping through each element and applying it? (The loop will take a lot of time as the tables will be large)
from scipy import special
import numpy as np
dummy_array = np.arange(20)
erf_array = special.erf(dummy_array)
It is essential that you import the special subpackage as from scipy import special. Importing just scipy as import scipy and then calling scipy.special.erf() won't work, as explained here and here.
you can use list comprehension to apply the function to each element at once
erf_array = [erf(element) for element in dummy_array)]

I am currently solving a problem for my class on Plancks blackbody function

import math
import matplotlib.pyplot as plt
import numpy as np
hc=1.23984186E3
k=1.3806503E-23
T=(np.linspace(5000,10000,50))
lamb = np.linspace(0.00001,.0000001,50)
print(len(lamb))
print (len(T))
planck_top=8*math.pi*hc
planck_bottom1=lamb*1000000
planck_bottom2=math.exp(hc//lamb*k*T)
planck=planck_top//planck_bottom
I keep getting this error here;
>
planck_bottom2=math.exp(hc//lamb*k*T)
TypeError: only size-1 arrays can be converted to Python scalars
I am not sure how to correct this, as we are dealing with a large array here
hc//lamb*k*T returns an array, and math.exp() can work with a number only. So, the following would work:
planck_bottom2=[math.exp(i) for i in hc//lamb*k*T]
It returns a list containing each number in the array hc//lamb*k*T correspondingly exponentiated.
You have another option of using numpy instead of math.
Using Numpy for Array Calculations
Just replace math by np since you already import numpy as np.
planck_top=8*np.pi*hc
planck_bottom2 = np.exp(hc//lamb*k*T)
About using math and/or numpy:
As an additional piece of information, I encourage you to look at the following references for evaluating when/if you should choose math and/or numpy.
What is the difference between import numpy and import math [duplicate]
Are NumPy's math functions faster than Python's?
"Math module functions cannot be used directly on ndarrays because they only accept scalar, not array arguments."

The difference between np.function and function [duplicate]

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.

python: importing module in package namespace

I wonder if there is some standard way to do something like
import scipy as sp
from scipy import interpolate as sp.interpolate
that is not allowed.
Specifically:
I'd like to know if there is some reason why the above is not allowed. If I'm developing my own package foo, it seems reasonable to pollute its namespace as little as possible.
Things like
import scipy as sp
__import__('scipy.interpolate')
do the job, but are not all that nice and the docs recommend not to use __import__, unless strictly necessarily. Similarly
import importlib
import scipy as sp
importlib.import_module('scipy.interpolate',sp)
does the job, but it is still ugly, even longer and puts importlib in the namespace...
Imported modules are treated like regular objects so if you really want to you can import a module and assign it to an arbitrary variable like so
import scipy as sp
from scipy import interpolate
sp.interpolate = interpolate
sp.interpolate will behave as expected, it just points to the interpolate module whenever you call sp.interpolate. They are the same object underneath, i.e
print sp.interpolate is interpolate
>>> True
Then to finally remove the original 'interpolate' pointer call
del interpolate

Categories