Memory layout
This lesson explains the memory layout using NumPy.
We'll cover the following...
The NumPy documentation defines the ndarray class very clearly:
An instance of class ndarray consists of a contiguous one-dimensional segment of computer memory (owned by the array, or by some other object), combined with an indexing scheme that maps N integers into the location of an item in the block.
Said differently, an array is mostly a contiguous block of memory whose parts can be accessed using an indexing scheme. Such indexing scheme is in turn defined by a shape and a data type and this is precisely what is needed when you define a new array:
import numpy as npZ = np.arange(9).reshape(3,3).astype(np.int16)print(Z)print(Z.itemsize)# returns size of Z in bytesprint(Z.shape)# returns the x dimension and y dimension of Zprint(Z.ndim)# dimension in Z i.e (2 in this case) since the array is 2D
Here, we know that itemsize is 2 bytes (int16
), the shape is (3,3) and
the number of dimensions is 2.
To calculate the dimension we can also use
len(Z.shape)
.
Furthermore, we can deduce the strides of the array that define the number of bytes to step in each dimension when traversing the array.
import numpy as npZ = np.arange(9).reshape(3,3).astype(np.int16)stride = Z.shape[1]*Z.itemsize, Z.itemsize # store stride of Zprint("Stride(as np.int16):",stride)print("Z.stride(np.16):",Z.strides)Z = np.arange(9).reshape(3,3).astype(np.int32)stride= Z.shape[1]*Z.itemsize, Z.itemsize #stores stride of Zprint("Stride(as np.int32):",stride)print("Z.stride(np.32):",Z.strides)
Here in this example, we have to skip 2 bytes (1 value) to move to the next column, but 6 bytes (3 values) to get to the same position in the next row. As such, the strides for the array Z
will be (6, 2).
With all this information, we know how to access a specific item (designed by an index tuple) and more precisely, how to compute the start and end ...