# Extending an existing matrix {:.no_toc} ## The goal Questions to [David Rotermund](mailto:davrot@uni-bremen.de) ## [numpy.tile](https://numpy.org/doc/stable/reference/generated/numpy.tile.html) ```python numpy.tile(A, reps) ``` > Construct an array by repeating A the number of times given by reps. > > If reps has length d, the result will have dimension of max(d, A.ndim). > > If A.ndim < d, A is promoted to be d-dimensional by prepending new axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication, or shape (1, 1, 3) for 3-D replication. If this is not the desired behavior, promote A to d-dimensions manually before calling this function. > > If A.ndim > d, reps is promoted to A.ndim by pre-pending 1’s to it. Thus for an A of shape (2, 3, 4, 5), a reps of (2, 2) is treated as (1, 1, 2, 2). > > Note : Although tile may be used for broadcasting, it is strongly recommended to use numpy’s broadcasting operations and functions. **You might want to first use numpy.newaxis​ to create the required additional axis and then use tile.** Adding a new dimension makes a copy: ```python import numpy as np a = np.arange(1, 5) print(a) # -> [1 2 3 4] print(a.shape) # -> (4,) b = a[np.newaxis, :] print(b.shape) # -> (1, 4) print(np.may_share_memory(a, b)) # -> True (View) c = np.tile(a, (1, 1)) print(c.shape) # -> (1, 4) print(np.may_share_memory(a, c)) # -> False (Copy) ``` Examples: ```python import numpy as np a = np.arange(1, 5)[np.newaxis, :] print(a) # -> [[1 2 3 4]] print(a.shape) # -> (1, 4) c = np.tile(a, (1, 1)) print(c) # -> [[1 2 3 4]] print(c.shape) # -> (1, 4) c = np.tile(a, (4, 1)) print(c) print(c.shape) # -> (4, 4) c = np.tile(a, (1, 4)) print(c) # -> [[1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4]] print(c.shape) # -> (1, 16) ``` Output: ```python [[1 2 3 4] [1 2 3 4] [1 2 3 4] [1 2 3 4]] ``` Be very careful if you haven’t newaxis-ed...​ ```python import numpy as np a = np.arange(1, 5) print(a) # -> [1 2 3 4] print(a.shape) # -> (4,) c = np.tile(a, (4)) print(c) # -> [1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4] print(c.shape) # -> (16,) c = np.tile(a, (1, 4)) print(c) # -> [[1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4]] print(c.shape) # -> (1, 16) c = np.tile(a, (4, 1)) print(c) print(c.shape) # -> (4, 4) print() c = np.tile(a, (4, 1, 1)) print(c) print(c.shape) # -> (4, 1, 4) print() c = np.tile(a, (1, 4, 1)) print(c) print(c.shape) # -> (1, 4, 4) print() c = np.tile(a, (1, 1, 4)) print(c) # -> [[[1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4]]] print(c.shape) # -> (1, 1, 16) ``` Output: ```python [[1 2 3 4] [1 2 3 4] [1 2 3 4] [1 2 3 4]] [[[1 2 3 4]] [[1 2 3 4]] [[1 2 3 4]] [[1 2 3 4]]] [[[1 2 3 4] [1 2 3 4] [1 2 3 4] [1 2 3 4]]] ``` ## [numpy.repeat](https://numpy.org/doc/stable/reference/generated/numpy.repeat.html#numpy-repeat) **Don’t confuse tile() with repeat()!​** ```python numpy.repeat(a, repeats, axis=None)[source] ``` > Repeat each element of an array after themselves ```python import numpy as np a = np.arange(1, 5) print(a) # -> [1 2 3 4] print(a.shape) # -> (4,) b = np.repeat(a, (4)) print(b) # -> [1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4] print(b.shape) # -> (16,) ``` ## [numpy.pad](https://numpy.org/doc/stable/reference/generated/numpy.pad.html) ```python numpy.pad(array, pad_width, mode='constant', **kwargs) ``` > Pad an array. > **pad_width** : {sequence, array_like, int} > > Number of values padded to the edges of each axis. ((before_1, after_1), ... (before_N, after_N)) unique pad widths for each axis. (before, after) or ((before, after),) yields same before and after pad for each axis. (pad,) or int is a shortcut for before = after = pad width for all axes. > **constant_values** : sequence or scalar, optional > > Used in ‘constant’. The values to set the padded values for each axis. > > ((before_1, after_1), ... (before_N, after_N)) unique pad constants for each axis. > > (before, after) or ((before, after),) yields same before and after constants for each axis. > > (constant,) or constant is a shortcut for before = after = constant for all axes. > > Default is 0. ```python import numpy as np a = np.arange(1, 5) print(a) # -> [1 2 3 4] print(a.shape) # -> (4,) print(np.pad(a, 2)) # -> [0 0 1 2 3 4 0 0] print(np.pad(a, [2, 3])) # -> [0 0 1 2 3 4 0 0 0] print(np.pad(a, [2, 3], constant_values=-1)) # -> [-1 -1 1 2 3 4 -1 -1 -1] ``` ```python import numpy as np a = np.arange(1, 5).reshape((1, 4)) print(a) # -> [[1 2 3 4]] print(a.shape) # -> (1, 4) print(np.pad(a, [[2, 3], [1, 1]])) ``` Output: ```python [[0 0 0 0 0 0] [0 0 0 0 0 0] [0 1 2 3 4 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0]] ``` ### Pad can do more complex padding patterns than just pad with constant values! > **mode** : str or function, optional > > One of the following string values or a user supplied function. ||| |---|---| |‘constant’ (default)|Pads with a constant value.| |‘edge’|Pads with the edge values of array.| |‘linear_ramp’|Pads with the linear ramp between end_value and the array edge value.| |‘maximum’|Pads with the maximum value of all or part of the vector along each axis.| |‘mean’|Pads with the mean value of all or part of the vector along each axis.| |‘median’|Pads with the median value of all or part of the vector along each axis.| |‘minimum’|Pads with the minimum value of all or part of the vector along each axis.| |‘reflect’|Pads with the reflection of the vector mirrored on the first and last values of the vector along each axis.| |‘symmetric’|Pads with the reflection of the vector mirrored along the edge of the array.| |‘wrap’|Pads with the wrap of the vector along the axis. The first values are used to pad the end and the end values are used to pad the beginning.| |‘empty’|Pads with undefined values.| ||Padding function, see Notes.|