Importing numpy and matplotlib

In [1]:
import numpy as np
import matplotlib.pyplot as plt
In [2]:
%matplotlib inline

Creating arrays

In [3]:
np.array([1, 2, 3])
Out[3]:
array([1, 2, 3])
In [4]:
np.array([1, 2, 3], dtype=np.float32)
Out[4]:
array([ 1.,  2.,  3.], dtype=float32)
In [5]:
np.array([[1, 2, 3], [4, 5, 6]])
Out[5]:
array([[1, 2, 3],
       [4, 5, 6]])
In [6]:
np.arange(5, 10)
Out[6]:
array([5, 6, 7, 8, 9])
In [8]:
np.linspace(5, 10, 10)
Out[8]:
array([  5.   ,   5.556,   6.111,   6.667,   7.222,   7.778,   8.333,   8.889,   9.444,  10.   ])
In [10]:
np.empty((3, 2))
Out[10]:
array([[ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.]])
In [11]:
np.zeros((3, 2))
Out[11]:
array([[ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.]])
In [12]:
np.ones((3, 2))
Out[12]:
array([[ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.]])
In [14]:
np.eye(3)
Out[14]:
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
In [15]:
np.diag([1, 2, 3])
Out[15]:
array([[1, 0, 0],
       [0, 2, 0],
       [0, 0, 3]])
In [16]:
np.repeat(3, 5)
Out[16]:
array([3, 3, 3, 3, 3])
In [17]:
np.repeat([[1, 2, 3]], 3, axis=0)
Out[17]:
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

Array properties

In [18]:
a = np.arange(3 * 4).reshape(3, -1)
In [19]:
a.shape
Out[19]:
(3, 4)
In [20]:
a.size
Out[20]:
12
In [21]:
a.dtype
Out[21]:
dtype('int64')
In [22]:
a.nbytes
Out[22]:
96

Random numbers

In [23]:
np.random.seed(0)
In [24]:
np.random.rand(3, 4)
Out[24]:
array([[ 0.549,  0.715,  0.603,  0.545],
       [ 0.424,  0.646,  0.438,  0.892],
       [ 0.964,  0.383,  0.792,  0.529]])
In [25]:
np.random.randn(3, 4)
Out[25]:
array([[ 0.761,  0.122,  0.444,  0.334],
       [ 1.494, -0.205,  0.313, -0.854],
       [-2.553,  0.654,  0.864, -0.742]])
In [28]:
plt.hist(np.random.normal(10, 2.0, 1000));
In [45]:
plt.hist(np.random.binomial(1, 0.8, 1000));

Vector to matrix conversion

In [30]:
v = np.arange(3)
v
Out[30]:
array([0, 1, 2])
In [31]:
v.reshape(-1, 1) # column matrix
Out[31]:
array([[0],
       [1],
       [2]])
In [32]:
v[:, np.newaxis] # column matrix
Out[32]:
array([[0],
       [1],
       [2]])
In [33]:
v.reshape(1, -1) # row vector
Out[33]:
array([[0, 1, 2]])
In [34]:
v[np.newaxis, :] # row vector
Out[34]:
array([[0, 1, 2]])
In [35]:
r = v[np.newaxis, :] # returns view -> no copy
r[0, 0] = 10
In [36]:
r
Out[36]:
array([[10,  1,  2]])
In [37]:
v
Out[37]:
array([10,  1,  2])

Matrix to vector conversion

In [38]:
A = np.arange(3 * 4).reshape(3, -1)
A
Out[38]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [39]:
A.flatten()
Out[39]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
In [40]:
A.flatten()[0] = 10
A
Out[40]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [41]:
A.ravel()
Out[41]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
In [43]:
A.ravel()[0] = 100
A
Out[43]:
array([[100,   1,   2,   3],
       [  4,   5,   6,   7],
       [  8,   9,  10,  11]])
In [44]:
A.ravel()
Out[44]:
array([100,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11])

Indexing

In [38]:
a = np.arange(10)
In [39]:
a[1]
Out[39]:
1
In [40]:
a[[0, 5]]
Out[40]:
array([0, 5])
In [41]:
a[-1]
Out[41]:
9
In [42]:
a[:5]
Out[42]:
array([0, 1, 2, 3, 4])
In [43]:
a[5:]
Out[43]:
array([5, 6, 7, 8, 9])
In [44]:
a[5::2]
Out[44]:
array([5, 7, 9])
In [45]:
b = a[::2]
In [46]:
b[2] = -1
In [47]:
b
Out[47]:
array([ 0,  2, -1,  6,  8])
In [48]:
a
Out[48]:
array([ 0,  1,  2,  3, -1,  5,  6,  7,  8,  9])
In [49]:
a[a > 5]
Out[49]:
array([6, 7, 8, 9])
In [50]:
A = np.arange(3 * 4).reshape(3, 4)
In [51]:
A
Out[51]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [52]:
A[1, :]
Out[52]:
array([4, 5, 6, 7])
In [53]:
b = A.take(1, axis=0)
In [54]:
A.take(1, axis=1)
Out[54]:
array([1, 5, 9])
In [55]:
b
Out[55]:
array([4, 5, 6, 7])
In [56]:
b[0] = 10
In [57]:
b
Out[57]:
array([10,  5,  6,  7])
In [58]:
A
Out[58]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

Operations

In [59]:
A = np.arange(1, 7).reshape(3,2)
A
Out[59]:
array([[1, 2],
       [3, 4],
       [5, 6]])
In [60]:
A * 2
Out[60]:
array([[ 2,  4],
       [ 6,  8],
       [10, 12]])
In [61]:
A + 2
Out[61]:
array([[3, 4],
       [5, 6],
       [7, 8]])
In [62]:
v = np.array([1, 2])
v
Out[62]:
array([1, 2])
In [63]:
A.dot(v)
Out[63]:
array([ 5, 11, 17])
In [64]:
v.dot(v)
Out[64]:
5
In [65]:
A.sum()
Out[65]:
21
In [66]:
A.sum(axis=0)
Out[66]:
array([ 9, 12])
In [67]:
A.sum(axis=1)
Out[67]:
array([ 3,  7, 11])
In [68]:
A.prod(axis=0)
Out[68]:
array([15, 48])
In [69]:
A.mean(axis=0)
Out[69]:
array([ 3.,  4.])
In [70]:
A.std(axis=0)
Out[70]:
array([ 1.633,  1.633])
In [71]:
A.min(axis=0)
Out[71]:
array([1, 2])

Broadcasting

In [72]:
A
Out[72]:
array([[1, 2],
       [3, 4],
       [5, 6]])
In [73]:
# Scaling rows
r = np.array([[2, 3]])
A * r
Out[73]:
array([[ 2,  6],
       [ 6, 12],
       [10, 18]])
In [74]:
# Scaling columns
c = np.array([1, 2, 3]).reshape(3, -1)
A * c
Out[74]:
array([[ 1,  2],
       [ 6,  8],
       [15, 18]])

General rule

<img src='figures/bcast.png', align='left'/>

A (2d array): 5 x 4 B (1d array): 1 Result (2d array): 5 x 4 A (2d array): 5 x 4 B (1d array): 4 Result (2d array): 5 x 4 A (3d array): 15 x 3 x 5 B (3d array): 15 x 1 x 5 Result (3d array): 15 x 3 x 5 A (3d array): 15 x 3 x 5 B (2d array): 3 x 5 Result (3d array): 15 x 3 x 5 A (3d array): 15 x 3 x 5 B (2d array): 3 x 1 Result (3d array): 15 x 3 x 5
In [75]:
A = np.ones((2, 3, 5))
b = np.arange(3).reshape(3, 1)
In [76]:
A
Out[76]:
array([[[ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.]],

       [[ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.]]])
In [77]:
b
Out[77]:
array([[0],
       [1],
       [2]])
In [78]:
A + b
Out[78]:
array([[[ 1.,  1.,  1.,  1.,  1.],
        [ 2.,  2.,  2.,  2.,  2.],
        [ 3.,  3.,  3.,  3.,  3.]],

       [[ 1.,  1.,  1.,  1.,  1.],
        [ 2.,  2.,  2.,  2.,  2.],
        [ 3.,  3.,  3.,  3.,  3.]]])

Performance considerations

  • C order: rows are contiguous in memory (row-major order)
  • Fortran order: columns are contiguous in memory (column-major order)
In [79]:
Ac = np.ones((10, 100000), order='C') # C order
Af = np.ones((10, 100000), order='F') # Fortran order
In [80]:
%timeit Ac.sum(axis=0)
1000 loops, best of 3: 895 µs per loop
In [81]:
%timeit Af.sum(axis=0)
100 loops, best of 3: 1.98 ms per loop
In [82]:
Ac = np.ones((100000, 10), order='C')
Af = np.ones((100000, 10), order='F')
In [83]:
%timeit Ac.sum(axis=1)
100 loops, best of 3: 2.08 ms per loop
In [84]:
%timeit Af.sum(axis=1)
1000 loops, best of 3: 886 µs per loop

Further readings