I took an example from view_as_blocks and tried my change style:
A = np.arange(4*4).reshape(4,4) B = view_as_blocks(A, block_shape=(2, 2)) print(A.__array_interface__) print(B.__array_interface__) C = B.reshape((2*2,2,2)) print(C.__array_interface__)
production:
{'typestr': '<i4', 'data': (153226600, False), 'shape': (4, 4), 'descr': [('', '<i4')], 'version': 3, 'strides': None} {'typestr': '<i4', 'data': (153226600, False), 'shape': (2, 2, 2, 2), 'descr': [('', '<i4')], 'version': 3, 'strides': (32, 8, 16, 4)} {'typestr': '<i4', 'data': (150895960, False), 'shape': (4, 2, 2), 'descr': [('', '<i4')], 'version': 3, 'strides': None}
The data pointer for A and B same; B is a view of A
But a pointer to C is different. It's a copy. This explains why there is so much time in your case.
Let's do it a little differently:
A = np.arange(4*4).reshape(4,4) B = view_as_blocks(A, block_shape=(2, 2)) print(A.__array_interface__) print(B.__array_interface__) C = B.reshape((2*2,1,2,2)) print(C.__array_interface__) D = as_strided(B, shape=(2*2,1,2,2)) print(D.__array_interface__) print(B[1,1,:,:]) print(C[3,0,:,:]) print(D[3,0,:,:])
production
1254:~/mypy$ python3 skshape.py {'strides': None, 'typestr': '<i4', 'version': 3, 'data': (154278744, False), 'shape': (4, 4), 'descr': [('', '<i4')]} {'strides': (32, 8, 16, 4), 'typestr': '<i4', 'version': 3, 'data': (154278744, False), 'shape': (2, 2, 2, 2), 'descr': [('', '<i4')]} {'strides': None, 'typestr': '<i4', 'version': 3, 'data': (155705400, False), 'shape': (4, 1, 2, 2), 'descr': [('', '<i4')]} {'strides': (32, 8, 16, 4), 'typestr': '<i4', 'version': 3, 'data': (154278744, False), 'shape': (4, 1, 2, 2), 'descr': [('', '<i4')]} [[10 11] [14 15]] [[10 11] [14 15]] [[ 154561960 -1217783696] [ 48 3905]]
Again, changing the form creates a copy. 2nd as_strides returns the view, but the walking one is compressed. It looks at the memory outside the original data buffer (this is part of why playing with steps is dangerous in itself).
In my example, consider the first angle value of each block
print(B[:,:,0,0]) print(C[:,0,0,0]) [[ 0 2] [ 8 10]] [ 0 2 8 10]
For B rows increase by 8, columns by 2; which is reflected in step (32,8) (4 * 8.4 * 2).
But in C steps (2,6,2) - a step cannot do this.
From this I conclude that change is not possible without copying.