Coding Example: How to find if one vector is view of the other?
Explore how to identify if one NumPy vector is a view of another by analyzing array memory layout. Learn to use strides and byte bounds properties to find slicing parameters and validate results with NumPy methods.
Problem Statement
Given two vectors Z1 and Z2. We would like to know if Z2 is a view of Z1 and if yes, what is this view?
Example
Given below is a running example to give you a better understanding:
Illustration
The below illustration shows what the two vectors Z1 and Z2 would look like:
╌╌╌┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬╌╌
Z1 │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
╌╌╌┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴╌╌
╌╌╌╌╌╌╌┬───┬╌╌╌┬───┬╌╌╌┬───┬╌╌╌┬───┬╌╌╌╌╌╌╌╌╌╌
Z2 │ 1 │ │ 3 │ │ 5 │ │ 7 │
╌╌╌╌╌╌╌┴───┴╌╌╌┴───┴╌╌╌┴───┴╌╌╌┴───┴╌╌╌╌╌╌╌╌╌╌
Step 1: Check if view exists?
The base method lets you know if the view really exists:
At this point, we know Z2 is a view of Z1, meaning Z2 can be expressed as
Z1[start:stop:step]. The difficulty is to find start, stop and
step.
Step 2: Find out the value of step
For the step, we can use the strides property of any array that
gives the number of bytes to go from one element to the other in each
dimension. In our case, and because both arrays are one-dimensional, we can
directly compare the first stride only:
Step 3: Find start and stop indices in the array
Next difficulty is to find the start and the stop indices.
To do this, we can take advantage of the byte_bounds method that returns a pointer to the
end-points of an array.
byte_bounds(Z1)[0] byte_bounds(Z1)[-1]
↓ ↓
╌╌╌┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬╌╌
Z1 │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
╌╌╌┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴╌╌
byte_bounds(Z2)[0] byte_bounds(Z2)[-1]
↓ ↓
╌╌╌╌╌╌╌┬───┬╌╌╌┬───┬╌╌╌┬───┬╌╌╌┬───┬╌╌╌╌╌╌╌╌╌╌
Z2 │ 1 │ │ 3 │ │ 5 │ │ 7 │
╌╌╌╌╌╌╌┴───┴╌╌╌┴───┴╌╌╌┴───┴╌╌╌┴───┴╌╌╌╌╌╌╌╌╌╌
Here, byte_bounds(Z1)[0] and byte_bounds(Z2)[0] returns a pointer to the start point of the array Z1 and Z2 respectively and byte_bounds(Z1)[-1] and byte_bounds(Z1)[-1] returns a pointer to the endpoints of Z1 and Z2 respectively.
Coding Challenge: Try it yourself!
Looking at the illustration, try solving this challenge below! You have to find the values of offset_start and offset_stop. Take the assumption that the code already imports the NumPy library as np.
Step 4: Convert the offsets into index values
Converting these offsets into index values is straightforward using the itemsize
and taking into account that the offset_stop is negative (end-bound of Z2
is logically smaller than end-bound of Z1 array). We thus need to add the
items size of Z1 to get the right end index.
Step 5: Test your result!
Last, we test our results by using the allclose method in NumPy. It returns True if the two arrays are equal element-wise by comparing the relative and absolute difference of the two arrays with the already set threshold value, called tolerance.
The next lesson provides a detailed solution to this problem, see you there!