In [1]:
import numpy as np

1. Write a function to generate square arrays of size $n \times n$ that increment by one in layers. For example, for n=11, we have

array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1],
       [1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1],
       [1, 2, 3, 4, 4, 4, 4, 4, 3, 2, 1],
       [1, 2, 3, 4, 5, 5, 5, 4, 3, 2, 1],
       [1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1],
       [1, 2, 3, 4, 5, 5, 5, 4, 3, 2, 1],
       [1, 2, 3, 4, 4, 4, 4, 4, 3, 2, 1],
       [1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1],
       [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])

Generate a $13 \times 13$ square.


In [31]:
def f(n):
    x = np.ones((n, n)).astype('int')
    for i in range(1, (n+1)//2):
        x[i:-i, i:-i] += 1
    return x

In [36]:
f(13)


Out[36]:
array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1],
       [1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1],
       [1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1],
       [1, 2, 3, 4, 5, 5, 5, 5, 5, 4, 3, 2, 1],
       [1, 2, 3, 4, 5, 6, 6, 6, 5, 4, 3, 2, 1],
       [1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1],
       [1, 2, 3, 4, 5, 6, 6, 6, 5, 4, 3, 2, 1],
       [1, 2, 3, 4, 5, 5, 5, 5, 5, 4, 3, 2, 1],
       [1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1],
       [1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1],
       [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])

2. Generate the following array starting from np.arange(1, 25)

array([[ 1,  5,  9, 13, 17, 21],
       [ 2,  6, 10, 14, 18, 22],
       [ 3,  7, 11, 15, 19, 23],
       [ 4,  8, 12, 16, 20, 24]])
  • Find the row sums
  • Find the column sums
  • Normalize so that each row sums to 1
  • Replace all numbers in the matrix with the number modulo 12 (e.g. 9 is unchange but 13 becomes 1)
  • Extract the 2 by 4 inner sub-block tha starts with 6 and ends with 19

In [38]:
x = np.arange(1, 25)
x = x.reshape((6,4)).T
x


Out[38]:
array([[ 1,  5,  9, 13, 17, 21],
       [ 2,  6, 10, 14, 18, 22],
       [ 3,  7, 11, 15, 19, 23],
       [ 4,  8, 12, 16, 20, 24]])

In [39]:
x.sum(axis=1)


Out[39]:
array([66, 72, 78, 84])

In [40]:
x.sum(axis=0)


Out[40]:
array([10, 26, 42, 58, 74, 90])

In [42]:
xn = x/x.sum(axis=1)[:, np.newaxis]
np.sum(xn, axis=1)


Out[42]:
array([ 1.,  1.,  1.,  1.])

In [43]:
x % 12


Out[43]:
array([[ 1,  5,  9,  1,  5,  9],
       [ 2,  6, 10,  2,  6, 10],
       [ 3,  7, 11,  3,  7, 11],
       [ 4,  8,  0,  4,  8,  0]])

In [44]:
x[1:3, 1:5]


Out[44]:
array([[ 6, 10, 14, 18],
       [ 7, 11, 15, 19]])

3. Create the $12 \times 12$ multiplicaiton table below using the vector np.arange(1, 13) and broadcasting.

array([[  1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12],
       [  2,   4,   6,   8,  10,  12,  14,  16,  18,  20,  22,  24],
       [  3,   6,   9,  12,  15,  18,  21,  24,  27,  30,  33,  36],
       [  4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  44,  48],
       [  5,  10,  15,  20,  25,  30,  35,  40,  45,  50,  55,  60],
       [  6,  12,  18,  24,  30,  36,  42,  48,  54,  60,  66,  72],
       [  7,  14,  21,  28,  35,  42,  49,  56,  63,  70,  77,  84],
       [  8,  16,  24,  32,  40,  48,  56,  64,  72,  80,  88,  96],
       [  9,  18,  27,  36,  45,  54,  63,  72,  81,  90,  99, 108],
       [ 10,  20,  30,  40,  50,  60,  70,  80,  90, 100, 110, 120],
       [ 11,  22,  33,  44,  55,  66,  77,  88,  99, 110, 121, 132],
       [ 12,  24,  36,  48,  60,  72,  84,  96, 108, 120, 132, 144]])

In [69]:
x = np.arange(1, 13)
x[:, np.newaxis] * x[np.newaxis, :]


Out[69]:
array([[  1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12],
       [  2,   4,   6,   8,  10,  12,  14,  16,  18,  20,  22,  24],
       [  3,   6,   9,  12,  15,  18,  21,  24,  27,  30,  33,  36],
       [  4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  44,  48],
       [  5,  10,  15,  20,  25,  30,  35,  40,  45,  50,  55,  60],
       [  6,  12,  18,  24,  30,  36,  42,  48,  54,  60,  66,  72],
       [  7,  14,  21,  28,  35,  42,  49,  56,  63,  70,  77,  84],
       [  8,  16,  24,  32,  40,  48,  56,  64,  72,  80,  88,  96],
       [  9,  18,  27,  36,  45,  54,  63,  72,  81,  90,  99, 108],
       [ 10,  20,  30,  40,  50,  60,  70,  80,  90, 100, 110, 120],
       [ 11,  22,  33,  44,  55,  66,  77,  88,  99, 110, 121, 132],
       [ 12,  24,  36,  48,  60,  72,  84,  96, 108, 120, 132, 144]])

4. Calculate the pairwise distance matrix between the column vectors of the following array (use Euclidean distance). This should be a $6 \times 6$ array. Try to calculate the distance matrix using different approaches (e.g. loops, broadcasting, scipy funcitons).

array([[ 1,  5,  9, 13, 17, 21],
       [ 2,  6, 10, 14, 18, 22],
       [ 3,  7, 11, 15, 19, 23],
       [ 4,  8, 12, 16, 20, 24]])

Plot the resulting distance matrix as a "heatmap" using matlplotlib.


In [76]:
x = np.arange(1, 25).reshape((6,4))
x


Out[76]:
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12],
       [13, 14, 15, 16],
       [17, 18, 19, 20],
       [21, 22, 23, 24]])

In [79]:
np.sqrt(np.sum((x[np.newaxis, :, :] - x[:, np.newaxis, :])**2, -1))


Out[79]:
array([[  0.,   8.,  16.,  24.,  32.,  40.],
       [  8.,   0.,   8.,  16.,  24.,  32.],
       [ 16.,   8.,   0.,   8.,  16.,  24.],
       [ 24.,  16.,   8.,   0.,   8.,  16.],
       [ 32.,  24.,  16.,   8.,   0.,   8.],
       [ 40.,  32.,  24.,  16.,   8.,   0.]])

In [75]:
from scipy.spatial import distance_matrix

In [78]:
distance_matrix(x, x)


Out[78]:
array([[  0.,   8.,  16.,  24.,  32.,  40.],
       [  8.,   0.,   8.,  16.,  24.,  32.],
       [ 16.,   8.,   0.,   8.,  16.,  24.],
       [ 24.,  16.,   8.,   0.,   8.,  16.],
       [ 32.,  24.,  16.,   8.,   0.,   8.],
       [ 40.,  32.,  24.,  16.,   8.,   0.]])