NumPy
is a well-documented, stable module where you will find important tools for scientific computing:
tools for the creation and manipulation of multidimensional arrays (e.g. matrices)
a sizable mathematical library
The documentation can be found here: NumPy User Guide
To import the module, we will use the following statement
import numpy as np
NumPy
allows you to easily create and manipulate arrays.
To create sequences of numbers, NumPy provides the function arange
analogous to range
that returns arrays instead of lists.
import numpy as np
x = np.arange(0,2.0,0.1) # creates array x[i]= i*0.1, i=0..19
print(x)
print(np.size(x)) # print the size (dimension) of x
print(x[0]) # print first element
print(x[1]) # print second element
print(x[19]) # print last element
#print(x[20]) # This will print: IndexError: index 20 is out of bounds for axis 0 with size 20
a = np.array ([[1,2,3], [4,5,6], [7,8,9]]) # create 3x3 array (matrix)
print(a)
b = 2 * a # Multiplication of array by scalar: b[i,j] = 2*a[i,j]
print(b)
c = a + b # Summation of arrays: c[i,j]= a[i,j]+b[i,j]
print(c)
d = np.dot(a, b) # Product of a by b: d[i,j]= a[i,k]*b[k,j] (summed over k)
print(d)
e= a * b # term by term product: e[i,j]=a[i,j]*b[i,j]
# (this does not give the standard product of matrices)
print(e)
You can convert a list to a numpy
array. Numpy
then allows you to apply mathematical
functions on the array, such as scalar multiplication, as was already illustrated in the previous
example:
Tcelcius = [20.1, 20.8, 21.9, 22.5, 20.9, 20.1] # this is a list of temperature values in Celcius
C = np.array(Tcelcius) # this is now a 1D array
print(C)
print(C * 9 / 5 + 32) # convert to Farhenheit
type(C)
An interesting functionality in NumPy
is its ability to slice through arrays to extract subarrays:
import numpy as np
t = np.array([1,2,3,4,5,6])
print(t[1:4]) # this gives t[i], i=1,2,3 (excluding both i=0 and i=4!)
print(t[:4]) # this prints t[i], i=0,1,2,3 (excluding i=4)
print(t[4:]) # this prints t[i], i=4 to the last index of array
print(t[:-1]) # this excludes the last element
print(t[1:-1]) # this excludes the first and last element
Another method to extract subsets of numpy
arrays is to use indexation with a mask.
import numpy as np
a = np.arange(6)**2 # this gives a[i]= i**2, i=0,1,2,3,4,5
print(a)
print(a > 10) # this gives a boolean array, of values True/False
print(a[a > 10]) # this gives a new array by extracting all values a[i]> 10
The copy of a NumPy
array does copy the content of the array. Use .copy()
to copy the array and its values.
import numpy as np
a = np.zeros((2, 2)) # The function zeros creates an array full of zeros
print(a)
b = a
print(b)
a[1, 1] = 10
print(b)
c = b.copy()
print(c)
b[1, 1] = 0
print(b)
print(c)
# The same rule applies to sliced arrays
d = np.arange(10)
e = d[:5]
d[0] = 10
print(e)
The NumPy
module offers lots of ways to create special arrays, to manipulate arrays, and to create operations on arrays.
import numpy as np
a = np.arange(10)
x= np.sum(a)
print(x)
m= np.mean(a)
print(m)
When arange
is used with floating point arguments, it is not possible to predict the number of elements obtained, due to the finite floating point precision. Use the function linspace
that receives as an argument the number of elements that we want, instead of the increment.
import numpy as np
from numpy import pi
a = np.linspace( 0, 2, 9 ) # creates an array of 9 elements from 0 to 2 (2 is included!)
print(a)
x = np.linspace( 0, 2*pi, 100 ) # useful to evaluate function at lots of points
f = np.sin(x) # create the array of elements f[i]= sin(x[i]), i=0..99
There is a fast and efficient way to generate pseudo-random numbers by using the random
package of the Numpy
module:
import numpy as np
a = np.random.random(10)
print(a)
print(type(a))
This will give you an array of 10 random float numbers in the interval $[0,1]$:
[ 0.25565389 0.0676878 0.74177835 0.2258494 0.03242723 0.34176716 0.5329745 0.42407123 0.40579087 0.97520252]
"<"class 'numpy.ndarray'">"
You can also obtain random integers with the NumPy
package randint
:
import numpy as np
outcome = np.random.randint(1, 7, size=10)
print(outcome)
This will generate 10 integers randomly sampled between 1 and 6:
[6 3 1 6 4 5 1 2 5 5]
A simple to find a numerical approximation of $\pi$ is to use a Monte Carlo simulation: this consists in randomly selecting points $(x_i,y_i), i= 1, \ldots, n$ in the unit square $[0,1]\times [0,1] $ and in determining the ratio $m/n$, where $m$ is number of points that satisfy $x_i^2 + y_i^2 \le 1$.
Here is a way to do this with numpy
:
import numpy as np
N = 10000
x, y = np.random.random((2, N)) # create a 2xN array of random numbers in the interval [0,1]
mask = x**2 + y**2 < 1 # mask which defines the interior of 1/4 disk
approx_pi= 4*np.mean(mask) # mean(mask) gives the fraction of points inside the 1/4 disk
error = abs( (approx_pi-np.pi)/np.pi )
print('Relative error is',100*error,'%' )