Many times we need to perform computations or things Python does not know how to do natively.
Other times, we want the same piece of code to work with other inputs (data, values, etc.)
What can we do?
There are two ways of defining functions in Python:
lambda
notation:my_function = lambda x: some_computations_based_on_x
lambda
notation is useful to create functions on the go, especially when passing a function to others. We'll see examples and use it quite a bit later when we go into data analyses.lambda
function can take any number of arguments, but can only have one expression, i.e., you cannot perform complex computations.def
statement:def my_function(x, y, z=Z):
'''
Explanation of what the function does
What are the inputs:
x: variable to be passed
y: variable to be passed
z: variable to be passed, Z is the default value
'''
perform_computations
return some_value_or_computation
def
statement can take any number of arguments, assign default values to them, and can have as many expressions as needed.def
and all lines below it are aligned in the def
statement. This is similar to the other statements we have seen so far.
Let's create a function that computes the square of a number. Let's do it first using an anonymous function.
my_square = lambda x: x**2
my_square(4)
16
my_square(9)
81
Now, let's create the same function using the def
statement, which we will call create/write a function as opposed to an anonymous function.
def my_square_fn(x):
'''
This function take an input x and return x^2.
Parameters:
-----------
x: float, integer or any other number
Returns:
--------
out = x**2
Example:
>>> out = my_square_fn(4)
>>> out
16
'''
return x**2
my_square_fn(4)
16
my_square_fn?
range(from, to, step)
creates a sequence of numbers from from
to to
increasing by step
list(range(2, 20, 3))
[2, 5, 8, 11, 14, 17]
list(range(5))
[0, 1, 2, 3, 4]
print(string)
prints a stringprint('The square of 100 is', my_square(100))
print('The square of 100 is ' + str(my_square(100)))
The square of 100 is 10000 The square of 100 is 10000
len(x)
returns the length of element x
len(range(100))
100
len('Some random string ndsyafsdasdwne')
33
type(x)
returns the type of x
type('hello')
str
type(3.1415)
float
type(10)
int
type([1, 'a', 3])
list
One of the reasons people like Python is that there are lots of ready to use functions and solutions out there
In order to use a package/module in Python or IPython, say mypackage
, you need to import it, by executing
import mypackage
After executing this command, you will have access to the functions and objects defined in mypackage
.
For example, if mypackage
has a function squared
that takes a real number x
and computes its square,
we can use this function by calling mypackage.squared(x)
.
Since the name of some packages might be too long, your can give them a nickname by importing them instead as
import mypackage as myp
so now we could compute the square of x
by calling myp.squared(x)
.
Sometimes we want to import only a function or a subpackage, in which case we use
from mypackage import mysubpackage as mysp
from mypackage import function
We will use various packages that will be useful to do computations, statistics, plots, data management, etc.
os is the fundamental module to interact with your computer's operating system.
With os
you can:
import os
os.getenv('HOME')
pics
directory exists¶os.path.exists('pics')
True
Matplotlib is the fundamental package for plotting in Python.
All other plotting packages are built on top of it and expand it.
You can find examples of plots in their Gallery.
It is the norm to import matplotlib and its pyplot component as follows (and I suggest you do the same):
import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib matlab_type
where matlab_type
can be inline
or widget
.
widget
provides interactive plots, while inline
generates static plots.
import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib widget
Let's plot a line connecting a few points in a plot
x = [0, 1, 2, 3]
y = [my_square(i) for i in x]
plt.plot(x, y, c='r', marker='o', linestyle=':', label=r'$y=x^2$')
plt.legend()
plt.show()
Let's plot various lines and points with different colors and styles, and add labels etc.
x = [i/10 for i in range(0, 100)]
y = [i**2 for i in x]
z = [100 - 1/4 * i**2 + i for i in x]
fig, ax = plt.subplots(figsize=(8,5))
ax.plot(x, y, c='r', marker='o', markersize=4, linestyle='-.', label=r'$y=x^2$')
ax.plot(x, z, c='b', marker='D', markersize=4, linestyle='-', label=r'$y=100-\frac{1}{4}x^2 + x$')
ax.set_xlabel(r'$x$', fontsize=18)
ax.set_ylabel(r'Value', fontsize=18)
ax.set_title(r'Some Plots', fontsize=24)
ax.legend(fontsize=18)
plt.savefig('./pics/some-plots.png')
plt.savefig('./pics/some-plots.pdf')
plt.show()
NumPy is one of the fundamental packages for scientific computing with Python.
It provides many functions, objects, elements, etc. for doing all kinds of numerical computations, e.g.,
It is the norm to import NumPy as follows (and I suggest you do the same):
import numpy as np
import numpy as np
Once it is imported we can start doing computations with it.
The main type of object we will use is a NumPy array, which we create by
my_array = np.array(list_of_numbers)
e.g.,
c = [1, 2]
d = [[1, 2], [3, 4]]
ca = np.array(c)
da = np.array(d)
ca
array([1, 2])
da
array([[1, 2], [3, 4]])
With our arrays we can easily perform computations on each element.
ca**2
array([1, 4])
da * 3
array([[ 3, 6], [ 9, 12]])
ca*da
array([[1, 4], [3, 8]])
Arrays also have their own functions and properties
print(ca.shape)
print(da.shape)
(2,) (2, 2)
print('da=', da)
print('Sum of all elements da.sum()=', da.sum())
print('Sum of all elements in each column da.sum(axis=0)=', da.sum(axis=0))
print('Sum of all elements in each row da.sum(axis=1)=', da.sum(axis=1))
print('dot product is ca.dot(da)=', ca.dot(da))
da= [[1 2] [3 4]] Sum of all elements da.sum()= 10 Sum of all elements in each column da.sum(axis=0)= [4 6] Sum of all elements in each row da.sum(axis=1)= [3 7] dot product is ca.dot(da)= [ 7 10]
print(np.ones((3,4)))
print(np.zeros((2,2)))
print(np.eye(2))
print(np.ones_like(ca))
[[1. 1. 1. 1.] [1. 1. 1. 1.] [1. 1. 1. 1.]] [[0. 0.] [0. 0.]] [[1. 0.] [0. 1.]] [1 1]
np.random
¶np.random.uniform(low, high, size)
¶np.random.uniform(-1,1,10)
array([ 0.08183555, -0.90068916, -0.3861001 , 0.24515804, -0.07788098, -0.24446539, -0.24307422, 0.34988979, 0.12040606, -0.86218082])
np.random.normal(loc, scale, size)
¶np.random.normal(10, 1, size=(3,3))
array([[ 9.86381478, 9.19635859, 9.51404729], [ 8.73820829, 10.38539136, 9.95531535], [10.33150078, 9.17957557, 8.48430286]])
Let's create a simple random walk and plot it. A random walk is a variable $x_t$ that satisfies $$ x_{t+1} = a_0 + x_t + \varepsilon_t $$ where $a_0$ is some real number, known as drift, and $\varepsilon_t$ is a random variable that is Normally distributed with mean 0 and standard deviation $\sigma^2$, i.e., $$ \varepsilon_t\sim\mathcal{N}(0,\sigma^2). $$ For simplicity, let's assume the drift $a_0=0$.
#np.random.seed(123456)
x0 = 0
x = [x0]
[x.append(x[-1] + np.random.normal() ) for i in range(500)]
fig, ax = plt.subplots(figsize=(8,5))
ax.plot(x)
plt.title(r'A simple random walk', fontsize=24)
plt.xlabel(r'Period $t$', fontsize=18)
plt.ylabel(r'$x_t$', fontsize=18)
plt.show()
def CobbDouglas(K=1, L=1, A=1, alpha=0.3):
'''
This function computes the level of output of a Cobb-Douglas production function.
Given values of K, L, A, and alpha it returns $A\cdot K^\alpha \cdot L^{1-\alpha}$.
Parameters:
-----------
K: float, integer or any other number, default=1
L: float, integer or any other number, default=1
A: float, integer or any other number, default=1
alpha: float between (0,1), default=0.3
Returns:
--------
out = A * K**alpha * L**(1-alpha)
Example:
>>> out = CobbDouglas(4, 9, 2, 1/2)
>>> out
12
'''
np.linspace(0, 5, 100)
function to create an array of values of $K$ with 100 point between 0 and 5.
plt.savefig
function.
Notebook written by Ömer Özak for his students in Economics at Southern Methodist University. Feel free to use, distribute, or contribute.