Numpy (Python3) tutorial

Basic idea of numpy

Manipulate array of numbers very efficiently

The bad example, whithout numpy:

In [1]:
import time
import math
xs = range(1000000)
t11 = time.time()
ys = []
for x in xs:
  ys.append(math.sqrt(x))

t12 = time.time()
print(t12-t11)
0.17665505409240723

The good example, with numpy:

In [2]:
import numpy as np
xs = np.arange(1000000)
t21 = time.time()
ys = np.sqrt(xs)
t22 = time.time()
print(t22-t21)
0.016564369201660156

The ratio:

In [3]:
print ((t12-t11)/(t22-t21))
10.664761932178019

Numpy objects

Array objets are sets of numbers of same type.

Some definitions:

|name | definition | |——————————–|————————————————————-| |size |total number of elements | |shape |integer tuple giving the number of elements in each dimension| |rank |size of “shape” corresponds to the number of dimensions | |dtype |type of elements in the array |

Some types:

type name type code
bolean Bool
unsigned UInt8, UInt16, UInt32, UInt64
integer Int8, Int16, Int32 (Int), Int64
float Float32, Float64 (Float)
complex Complex32, Complex64 (Complex)

Importing Numpy

In [6]:
import numpy as np

Creating a Numpy array

creating it explicitely:

In [8]:
x = np.array([1,2,3])
x
Out[8]:
array([1, 2, 3])
In [9]:
y = np.array([[1,2],[3,4],[5,6]],float)
y
Out[9]:
array([[ 1.,  2.],
       [ 3.,  4.],
       [ 5.,  6.]])
In [10]:
x.size
Out[10]:
3
In [11]:
x.shape
Out[11]:
(3,)
In [12]:
x.dtype
Out[12]:
dtype('int64')
In [13]:
y.size
Out[13]:
6
In [14]:
y.shape
Out[14]:
(3, 2)
In [15]:
y.dtype
Out[15]:
dtype('float64')

creating from a python list:

In [16]:
np.asarray((1,2,3))
Out[16]:
array([1, 2, 3])

creating from building function:

In [17]:
np.zeros(3)
Out[17]:
array([ 0.,  0.,  0.])
In [18]:
np.zeros((5,5))
Out[18]:
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])
In [19]:
np.ones((2,3),float)
Out[19]:
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
In [22]:
np.arange(10)
Out[22]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [23]:
np.identity(10)
Out[23]:
array([[ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.]])
In [25]:
np.linspace(0,np.pi,10)
Out[25]:
array([ 0.        ,  0.34906585,  0.6981317 ,  1.04719755,  1.3962634 ,
        1.74532925,  2.0943951 ,  2.44346095,  2.7925268 ,  3.14159265])

creating from a function:

In [26]:
def x2(x):
  return x*x

def xy(x,y):
  return x*y
In [27]:
np.fromfunction(x2,(5,))
Out[27]:
array([  0.,   1.,   4.,   9.,  16.])
In [28]:
np.fromfunction(xy,(5,5))
Out[28]:
array([[  0.,   0.,   0.,   0.,   0.],
       [  0.,   1.,   2.,   3.,   4.],
       [  0.,   2.,   4.,   6.,   8.],
       [  0.,   3.,   6.,   9.,  12.],
       [  0.,   4.,   8.,  12.,  16.]])

change dimension:

In [29]:
x = np.array([1,2,3,4,5,6,7,8,9,10,11,12])
x
Out[29]:
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])
In [30]:
np.reshape(x,(2,6))
Out[30]:
array([[ 1,  2,  3,  4,  5,  6],
       [ 7,  8,  9, 10, 11, 12]])
In [31]:
x.shape = (6,2)
x
Out[31]:
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10],
       [11, 12]])
In [32]:
y = np.reshape(x,(3,4))
y
Out[32]:
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
In [33]:
np.reshape(y,(12,))
y
Out[33]:
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])

casting:

In [34]:
x = np.array([1,2,3],float)
x
Out[34]:
array([ 1.,  2.,  3.])
In [35]:
y = np.array([1,2,3],int)
y
Out[35]:
array([1, 2, 3])
In [36]:
(x+y).dtype
Out[36]:
dtype('float64')

Indexing arrays

Retreieve an element or a group of elements:

In [38]:
a = np.arange(12)
a
Out[38]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
In [39]:
a[0]
Out[39]:
0
In [40]:
a[1]=-a[1]
a
Out[40]:
array([ 0, -1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
In [41]:
a[2:4]
Out[41]:
array([2, 3])
In [42]:
a[2:4] = [-2,-3]
a
Out[42]:
array([ 0, -1, -2, -3,  4,  5,  6,  7,  8,  9, 10, 11])
In [43]:
a[5:]
Out[43]:
array([ 5,  6,  7,  8,  9, 10, 11])

Multidimentional arrays

In [47]:
a.shape = (3,4)
a
Out[47]:
array([[ 0, -1, -2, -3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [48]:
a[2,0]
Out[48]:
8
In [49]:
a[0]
Out[49]:
array([ 0, -1, -2, -3])
In [50]:
a[0,:]
Out[50]:
array([ 0, -1, -2, -3])
In [51]:
a[:,0]
Out[51]:
array([0, 4, 8])
In [52]:
a[1:,1:]
Out[52]:
array([[ 5,  6,  7],
       [ 9, 10, 11]])
In [53]:
a[1:,1:] = np.ones((2,3))
a
Out[53]:
array([[ 0, -1, -2, -3],
       [ 4,  1,  1,  1],
       [ 8,  1,  1,  1]])

Using a list of indexes:

In [54]:
a = np.arange(12)**2
a
Out[54]:
array([  0,   1,   4,   9,  16,  25,  36,  49,  64,  81, 100, 121])
In [55]:
index = [0,4,3]
a[index]
Out[55]:
array([ 0, 16,  9])
In [56]:
a[np.arange(3)]
Out[56]:
array([0, 1, 4])

another example:

In [57]:
a = np.reshape(a,(3,4))
a
Out[57]:
array([[  0,   1,   4,   9],
       [ 16,  25,  36,  49],
       [ 64,  81, 100, 121]])
In [59]:
ind1 = [1,2]
ind2 = [0,3]
a[ind1,ind2]
Out[59]:
array([ 16, 121])

and another one:

In [63]:
ind1 = np.array([[1,2],[0,2]])
ind1
Out[63]:
array([[1, 2],
       [0, 2]])
In [64]:
ind2 = np.array([[0,3],[1,2]])
ind2
Out[64]:
array([[0, 3],
       [1, 2]])
In [65]:
a[ind1,ind2]
Out[65]:
array([[ 16, 121],
       [  1, 100]])

Special values

nan, inf:

In [66]:
x = np.array([0,1],float)
y = x/0.
y
/usr/lib/python3.6/site-packages/ipykernel_launcher.py:2: RuntimeWarning: divide by zero encountered in true_divide

/usr/lib/python3.6/site-packages/ipykernel_launcher.py:2: RuntimeWarning: invalid value encountered in true_divide

Out[66]:
array([ nan,  inf])

track special values:

In [67]:
np.isnan(y)
Out[67]:
array([ True, False], dtype=bool)
In [68]:
np.isinf(y)
Out[68]:
array([False,  True], dtype=bool)
In [69]:
np.isfinite(y)
Out[69]:
array([False, False], dtype=bool)
In [70]:
np.isfinite(x)
Out[70]:
array([ True,  True], dtype=bool)

replace bad values:

In [71]:
y[np.isnan(y)]=0
y[np.isinf(y)]=1e10
y
Out[71]:
array([  0.00000000e+00,   1.00000000e+10])

Array methods

Some important methods:

In [72]:
x = np.array([0,4,3,2])
x.min()
Out[72]:
0
In [73]:
x.max()
Out[73]:
4
In [74]:
x.mean()
Out[74]:
2.25
In [75]:
x.std()
Out[75]:
1.479019945774904
In [76]:
x.argmax()
Out[76]:
1
In [77]:
x.argmin()
Out[77]:
0
In [78]:
x.argsort()
Out[78]:
array([0, 3, 2, 1])
In [79]:
x.sum()
Out[79]:
9
In [80]:
x.conjugate()
Out[80]:
array([0, 4, 3, 2])

Operations on arrays (ufunc)

Operations elements by elements return an array of same shape.

|add (+) |substract (-) |multiply (*) |divide () | |——————|——————|—————–|—————–| |remainder (%) |power (**) | | | |abs |fabs |floor |ceil | |fmod |conjugate | | | |maximum |minimum | | | |cos |sin |arccos |arcsin | |cosh |sinh |arccosh |arcsinh | |tan |arctan |tanh |arctanh | |log |log10 |exp | | |greater (>) |greater_equal(>=) |equal(==) | | |less (<) |less_equal(<=) |not_equal(!=) | | |logical_or |logical_xor |logical_not |logical_and | |bitwise_or () |bitwise_xor (^) |bitwise_not (~) |bitwise_and (&) | |rshift(>>) |lshift(<<) | | |

Examples:

In [81]:
x = np.array([1,2,3],float)
y = np.array([4,5,6],float)
In [82]:
x/y
Out[82]:
array([ 0.25,  0.4 ,  0.5 ])
In [85]:
x**2
Out[85]:
array([1, 4, 9])
In [86]:
x = np.array([1,2,3])
x
Out[86]:
array([1, 2, 3])
In [87]:
y = np.reshape(np.arange(12),(4,3))
y
Out[87]:
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])

sum a vector with a matrix

In [89]:
x+y
Out[89]:
array([[ 1,  3,  5],
       [ 4,  6,  8],
       [ 7,  9, 11],
       [10, 12, 14]])
In [90]:
y*= 10
y
Out[90]:
array([[  0,  10,  20],
       [ 30,  40,  50],
       [ 60,  70,  80],
       [ 90, 100, 110]])
In [91]:
y+= y
y
Out[91]:
array([[  0,  20,  40],
       [ 60,  80, 100],
       [120, 140, 160],
       [180, 200, 220]])

compare arrays

In [94]:
x = np.array([1,2,3])
y = np.array([0,2,3],float)
(x>y)
Out[94]:
array([ True, False, False], dtype=bool)
In [95]:
(x==2)
Out[95]:
array([False,  True, False], dtype=bool)
In [96]:
(x>y) | (x==2)
Out[96]:
array([ True,  True, False], dtype=bool)

Array functions

General functions on arrays:

Example: replace specific values in a vectors:

In [97]:
x = np.arange(16)
x = np.reshape(x,(4,4))
x
Out[97]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
In [98]:
y = np.fmod(x,3)
y
Out[98]:
array([[0, 1, 2, 0],
       [1, 2, 0, 1],
       [2, 0, 1, 2],
       [0, 1, 2, 0]])
In [100]:
np.where((y==0),-1,y)
Out[100]:
array([[-1,  1,  2, -1],
       [ 1,  2, -1,  1],
       [ 2, -1,  1,  2],
       [-1,  1,  2, -1]])

Replace values using a mask:

In [106]:
x = np.arange(16)
x = np.reshape(x,(4,4))
x
Out[106]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
In [107]:
mask = np.where((y==0),1,0)
mask
Out[107]:
array([[1, 0, 0, 1],
       [0, 0, 1, 0],
       [0, 1, 0, 0],
       [1, 0, 0, 1]])
In [108]:
np.putmask(x,mask,y)
x
Out[108]:
array([[ 0,  1,  2,  0],
       [ 4,  5,  0,  7],
       [ 8,  0, 10, 11],
       [ 0, 13, 14,  0]])

Example: remove bad values in a vector:

In [110]:
x = np.array([0,1,2,3,4,5],float)
y = np.array([1,0,3,0,5,2],float)
ly = np.log10(y)
ly
/usr/lib/python3.6/site-packages/ipykernel_launcher.py:3: RuntimeWarning: divide by zero encountered in log10
  This is separate from the ipykernel package so we can avoid doing imports until
Out[110]:
array([ 0.        ,        -inf,  0.47712125,        -inf,  0.69897   ,
        0.30103   ])
In [111]:
c = (y!=0)
c
Out[111]:
array([ True, False,  True, False,  True,  True], dtype=bool)
In [112]:
x = np.compress(c,x)
x
Out[112]:
array([ 0.,  2.,  4.,  5.])
In [113]:
y = np.compress(c,y)
y
Out[113]:
array([ 1.,  3.,  5.,  2.])
In [114]:
ly = np.log10(y)
ly
Out[114]:
array([ 0.        ,  0.47712125,  0.69897   ,  0.30103   ])

Other very usefull functions:

ravel:

In [115]:
x = np.identity(3)
x
Out[115]:
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
In [116]:
np.ravel(x)
Out[116]:
array([ 1.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  1.])
In [119]:
x = np.array([1,2,3])
y = np.array([4,5,6])

concatenate:

In [120]:
z = np.concatenate((x,y))
z
Out[120]:
array([1, 2, 3, 4, 5, 6])

clip:

In [121]:
np.clip(z,2,5)
Out[121]:
array([2, 2, 3, 4, 5, 5])

sum:

In [124]:
np.sum(z)
Out[124]:
21

Matrix operations: transpose, diagonal, trace, dot product:

In [125]:
a = np.array([1,2])
b = np.array([4,5])
In [126]:
np.dot(a,b)
Out[126]:
14

Polynomials:

In [127]:
from numpy import poly1d
p1 = poly1d([3,4,5])
p2 = poly1d([1,1,1])
print(p1)
   2
3 x + 4 x + 5
In [128]:
print(p1+p2)
   2
4 x + 5 x + 6
In [129]:
print(p1.deriv())

6 x + 4
In [130]:
print(p1.integ(k=6))
   3     2
1 x + 2 x + 5 x + 6
In [ ]:

In [ ]: