Changing the look of an n-dimensional array without using reshape

tl; dr Can I change the appearance of a numpy array from 5x5x5x3x3x3 to 125x1x1x3x3x3 without using numpy.reshape?

I would like to perform a slip operation (with different steps) on that (size MxMxM). A sliding window array can be generated using numpy.lib.stride_tricks.as_strided , as previously suggested by Benjamin and Eickenberg , and demonstrated in the code snippet below, which uses a helper method from skimage that uses as_strided .

Exiting this helper method gives me the form NxNxNxnxnxn, but I would prefer the form to be N ^ 3x1xnxnxn. Although I can use np.reshape to achieve this, np.resape is slow if the volume becomes large (> 100x100x100), which I'm not sure why. I thought I could use as_stride to change the output, but with numpy errors (code snippet below). Any ideas on how I can get an idea of ​​exiting a helper method like N ** 3x1xnxnxn without using np.reshape?

 import numpy as np import skimage l = 15 s = 3 X = np.ones((l,l,l)) print('actual shape',X.shape) view = skimage.util.shape.view_as_blocks(X,(s,s,s)) print('original view',view.shape) new_shape = ((l/s)**3,1,1,s,s,s) print('new view',new_shape) view_correct = view.reshape(new_shape) print(view_correct.shape) print('coord:','124,0,0,2,2,2','value:',view_correct[124,0,0,2,2,2]) view_incorrect = np.lib.stride_tricks.as_strided(view, shape=new_shape) print(view_incorrect.shape) print('coord:','124,0,0,2,2,2','value:',view_incorrect[124,0,0,2,2,2]) 
+3
python numpy scikit-image
source share
1 answer

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.

+1
source share

All Articles