c2a90628d1
Signed-off-by: David Rotermund <54365609+davrot@users.noreply.github.com> |
||
---|---|---|
.. | ||
README.md |
Dimensions and shape
{:.no_toc}
* TOC {:toc}The goal
Matrices have dimensions. But how to add and remove extra dimensions (i.e. dimensions with length 1)?
Questions to David Rotermund
numpy.ndarray.shape
ndarray.shape
Tuple of array dimensions.
The shape property is usually used to get the current shape of an array, but may also be used to reshape the array in-place by assigning a tuple of array dimensions to it. As with numpy.reshape, one of the new shape dimensions can be -1, in which case its value is inferred from the size of the array and the remaining dimensions. Reshaping an array in-place will fail if a copy is required.
import numpy as np
data = np.zeros((2, 4, 2, 7, 2))
print(data.shape) # -> (2, 4, 2, 7, 2)
Vanishing dimensions
import numpy as np
data = np.zeros((5, 3, 2))
# All the same dimensionwise
print(data.shape) # -> (5, 3, 2)
print(data[:].shape) # -> (5, 3, 2)
print(data[:, :, :].shape) # -> (5, 3, 2)
print(data[...].shape) # -> (5, 3, 2)
print(data[0, :, :].shape) # -> (3, 2)
print(data[:, 0, :].shape) # -> (5, 2)
print(data[:, :, 0].shape) # -> (5, 3)
print(data[:, 0, 0].shape) # -> (5,)
print(data[0, :, 0].shape) # -> (3,)
print(data[0, 0, :].shape) # -> (2,)
print(data[0, 0, 0].shape) # -> ()
print(type(data[0, 0, 0])) # -> <class 'numpy.float64'>
keepdims
There are functions like
ndarray.sum(axis=None, dtype=None, out=None, keepdims=False, initial=0, where=True)
ndarray.mean(axis=None, dtype=None, out=None, keepdims=False, *, where=True)
ndarray.prod(axis=None, dtype=None, out=None, keepdims=False, initial=1, where=True)
ndarray.max(axis=None, out=None, keepdims=False, initial=<no value>, where=True)
ndarray.min(axis=None, out=None, keepdims=False, initial=<no value>, where=True)
ndarray.argmax(axis=None, out=None, *, keepdims=False)
ndarray.argmin(axis=None, out=None, *, keepdims=False)
that normally make one dimension vanish. However, often this type of functions have an argument keepdims that keeps this dimension alive.
import numpy as np
data = np.zeros((5, 3, 2))
# All the same dimensionwise
print(data.shape) # -> (5, 3, 2)
print(data.sum().shape) # -> ()
print(data.sum(axis=0).shape) # -> (3, 2)
print(data.sum(axis=1).shape) # -> (5, 2)
print(data.sum(axis=2).shape) # -> (5, 3)
# You can use keepdims:
print(data.sum(axis=0, keepdims=True).shape) # -> (1, 3, 2)
print(data.sum(axis=1, keepdims=True).shape) # -> (5, 1, 2)
print(data.sum(axis=2, keepdims=True).shape) # -> (5, 3, 1)
As as reminder, shape is only availabe for np.ndarray and torch.Tensor matrices:
z = int(7)
print(np.array(z).shape) # -> ()
print(type(np.array(z))) # -> <class 'numpy.ndarray'>
print(type(z)) # -> <class 'int'>
print(z.shape) # -> AttributeError: 'int' object has no attribute 'shape'
Stop vanishing dimensions
One way to do stop vanishing dimensions is to use slices of thickness 1. If you want the nth element, then use n:n+1:
import numpy as np
data = np.zeros((5, 3, 2))
# All the same dimensionwise
print(data.shape) # -> (5, 3, 2)
print(data[0:1, :, :].shape) # -> (1, 3, 2)
print(data[:, 0:1, :].shape) # -> (5, 1, 2)
print(data[:, :, 0:1].shape) # -> (5, 3, 1)
print(data[:, 0:1, 0:1].shape) # -> (5, 1, 1)
print(data[0:1, :, 0:1].shape) # -> (1, 3, 1)
print(data[0:1, 0:1, :].shape) # -> (1, 1, 2)
print(data[0:1, 0:1, 0:1].shape) # -> (1, 1, 1)
print(type(data[0:1, 0:1, 0:1])) # -> <class 'numpy.ndarray'>
Please understand this creates a view which is connected to original data. If necessary make a copy().
Adding dimensions with np.newaxis
numpy.newaxis
A convenient alias for None, useful for indexing arrays.
import numpy as np
data = np.zeros((2))
print(data.shape) # -> (2,)
print(data[:, np.newaxis].shape) # -> (2, 1)
print(data[np.newaxis, :].shape) # -> (1, 2)
print(data[:, np.newaxis, np.newaxis].shape) # -> (2, 1, 1)
print(data[np.newaxis, :, np.newaxis].shape) # -> (1, 2, 1)
print(data[:, np.newaxis, np.newaxis].shape) # -> (2, 1, 1)
Adding dimensions with numpy.expand_dims
In the case you don’t like newaxis for adding a new dimension...
numpy.expand_dims(a, axis)
Expand the shape of an array.
Insert a new axis that will appear at the axis position in the expanded array shape.
import numpy as np
data = np.zeros((2))
print(data.shape) # -> (2,)
print(np.expand_dims(data, axis=0).shape) # -> (1, 2)
print(np.expand_dims(data, axis=1).shape) # -> (2, 1)
print(np.expand_dims(data, axis=(1, 2, 3)).shape) # -> (2, 1, 1, 1)
Removing dimensions with numpy.squeeze
numpy.squeeze(a, axis=None)
Remove axes of length one from a.
import numpy as np
data = np.zeros((1, 2, 1, 1))
print(data.shape) # -> (1, 2, 1, 1)
print(np.squeeze(data).shape) # -> (2,)
print(np.squeeze(data, axis=0).shape) # -> (2, 1, 1)
print(np.squeeze(data, axis=2).shape) # -> (1, 2, 1)
print(np.squeeze(data, axis=3).shape) # -> (1, 2, 1)
print(np.squeeze(data, axis=(0, -1)).shape) # -> (2, 1)
print(
np.squeeze(data, axis=1).shape
) # -> ValueError: cannot select an axis to squeeze out which has size not equal to one