I am trying to replicate transpose + flatten method of numpy. In order to take transpose, I only swap the last dimension with the dimension I want to transpose. Then I transform item positions to
linear index. However item ordering comes out different with numpy.flatten(). How can i achieve same behavior? Desired output is numpy flatten output. The question is how does numpy achieve this?
Here is the example:
Step 1:
Let's say I have an 1d array of K=16 sequential integers:
1d_Arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])`
Step 2:
I reshape it to (2,2,4) dimensions. (row, col, depth) == (2,2,4)
3d_Arr = 1d_Arr.reshape((2,2,4))
Step 3:
Take dimension-wise transpose.
Notice they all swapped with the last index of the 3d_Arr.shape.
row_transpose = 3d_Arr.transpose((2,1,0)).flatten()
col_transpose = 3d_Arr.transpose((0,2,1)).flatten()
depth_transpose = 3d_Arr.transpose((0,1,2)).flatten()
Step 4:
Print indices by using:
# returns where is the element in the array. Such as (2,0,1)
# i: is a value of an array item.
indices = np.where(anArray == i)
# returns the current (some?) linear index for the given indices
linear_idx = np.ravel_multi_index(indices, anArray.shape)
Results:
1d_Array (Linear) :
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
Desired output:
row-transpose-flatten = [ 0 8 4 12 1 9 5 13 2 10 6 14 3 11 7 15]
col-transpose-flatten = [ 0 4 1 5 2 6 3 7 8 12 9 13 10 14 11 15]
depth-transpose-flatten = [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]`
My strategy
DEPTH-TRANSPOSE :
Element Value -> Element indices -> ravel_multi_index for Element indices
0 -> (array([0]), array([0]), array([0])) -> [0]
1 -> (array([0]), array([0]), array([1])) -> [1]
2 -> (array([0]), array([0]), array([2])) -> [2]
3 -> (array([0]), array([0]), array([3])) -> [3]
4 -> (array([0]), array([1]), array([0])) -> [4]
5 -> (array([0]), array([1]), array([1])) -> [5]
6 -> (array([0]), array([1]), array([2])) -> [6]
7 -> (array([0]), array([1]), array([3])) -> [7]
8 -> (array([1]), array([0]), array([0])) -> [8]
9 -> (array([1]), array([0]), array([1])) -> [9]
10 -> (array([1]), array([0]), array([2])) -> [10]
11 -> (array([1]), array([0]), array([3])) -> [11]
12 -> (array([1]), array([1]), array([0])) -> [12]
13 -> (array([1]), array([1]), array([1])) -> [13]
14 -> (array([1]), array([1]), array([2])) -> [14]
15 -> (array([1]), array([1]), array([3])) -> [15]
ROW-TRANSPOSE :
Element Value -> Element indices -> ravel_multi_index for Element indices
0 -> (array([0]), array([0]), array([0])) -> [0]
1 -> (array([1]), array([0]), array([0])) -> [4]
2 -> (array([2]), array([0]), array([0])) -> [8]
3 -> (array([3]), array([0]), array([0])) -> [12]
4 -> (array([0]), array([1]), array([0])) -> [2]
5 -> (array([1]), array([1]), array([0])) -> [6]
6 -> (array([2]), array([1]), array([0])) -> [10]
7 -> (array([3]), array([1]), array([0])) -> [14]
8 -> (array([0]), array([0]), array([1])) -> [1]
9 -> (array([1]), array([0]), array([1])) -> [5]
10 -> (array([2]), array([0]), array([1])) -> [9]
11 -> (array([3]), array([0]), array([1])) -> [13]
12 -> (array([0]), array([1]), array([1])) -> [3]
13 -> (array([1]), array([1]), array([1])) -> [7]
14 -> (array([2]), array([1]), array([1])) -> [11]
15 -> (array([3]), array([1]), array([1])) -> [15]`
As it can be seen above, The strategy for flatten() operation is different. Numpy flatten output pattern and my strategy gives different outputs. Desired output is numpy flatten output.
The question is how does numpy achieve this ?
threeD_Arr[1,0,0]is 8 and not 4 (3d_Arris not a valid python variable name). So this does not seem to be an issue of how numpy uses transpose and flatten. This is also inconsistent between your depth- and row-tranpose. For depth-tranpose you havethreeD_Arr[1,0,0]correctly as 8.numpyusesshapeandstridesto make multidimensional arrays.transposejust makes aviewwith different strides (and shape).flattenis a copy to 1d, using the source strides to traverse the array's databuffer. You need to understand array storage.