Python ravel vs. transpose when used in reshape

I have a 2D-array v , v.shape=(M_1,M_2) , I want to convert a three-dimensional array v.shape=(M_2,N_1,N_2) ) and M_1=N_1*N_2 .

I came up with the following lines that give the same result:

 np.reshape(vT, reshape_tuple) 

and

 np.reshape(v.ravel(order='F'), reshape_tuple) 

for reshape_tuple=(M_2,N_1,N_2) .

Which one is better to calculate in any sense (compass, time, memory, etc.), if the initial v is a huge (possibly complex) matrix?

I assume that the use of better transposition, but if reshape makes automatic ravel , it is possible that option ravel faster (although reshape can perform ravel in C or Fortran, and it is not clear)?

+5
source share
1 answer

The order in which they do things - change, change steps and make a copy - is different, but they end up doing the same thing.

I like to use __array_interface__ , to see where the data buffer, and other changes. I suppose I should add flags , to see the order . But we / you know that transpose have changed the order to F , right?

 In [549]: x=np.arange(6).reshape(2,3) In [550]: x.__array_interface__ Out[550]: {'data': (187732024, False), 'descr': [('', '<i4')], 'shape': (2, 3), 'strides': None, 'typestr': '<i4', 'version': 3} 

transpose is a view with a different shape, steps and order:

 In [551]: xT__array_interface__ Out[551]: {'data': (187732024, False), 'descr': [('', '<i4')], 'shape': (3, 2), 'strides': (4, 12), 'typestr': '<i4', 'version': 3} 

ravel with a different order is a copy (another data buffer pointer)

 In [552]: x.ravel(order='F').__array_interface__ Out[552]: {'data': (182286992, False), 'descr': [('', '<i4')], 'shape': (6,), 'strides': None, 'typestr': '<i4', 'version': 3} ') .__ array_interface__ In [552]: x.ravel(order='F').__array_interface__ Out[552]: {'data': (182286992, False), 'descr': [('', '<i4')], 'shape': (6,), 'strides': None, 'typestr': '<i4', 'version': 3} 

transpose ravel is also a copy. I think that the same data pointer - it's just a case of memory re-use (as I do not assign a variable), but it can be verified.

 In [553]: xTravel().__array_interface__ Out[553]: {'data': (182286992, False), 'descr': [('', '<i4')], 'shape': (6,), 'strides': None, 'typestr': '<i4', 'version': 3} 

add change:

 In [554]: xTravel().reshape(2,3).__array_interface__ Out[554]: {'data': (182286992, False), 'descr': [('', '<i4')], 'shape': (2, 3), 'strides': None, 'typestr': '<i4', 'version': 3} In [555]: x.ravel(order='F').reshape(2,3).__array_interface__ Out[555]: {'data': (182286992, False), 'descr': [('', '<i4')], 'shape': (2, 3), 'strides': None, 'typestr': '<i4', 'version': 3} ) .__ array_interface__. In [554]: xTravel().reshape(2,3).__array_interface__ Out[554]: {'data': (182286992, False), 'descr': [('', '<i4')], 'shape': (2, 3), 'strides': None, 'typestr': '<i4', 'version': 3} In [555]: x.ravel(order='F').reshape(2,3).__array_interface__ Out[555]: {'data': (182286992, False), 'descr': [('', '<i4')], 'shape': (2, 3), 'strides': None, 'typestr': '<i4', 'version': 3} ') reshape (2,3) .__ array_interface__. In [554]: xTravel().reshape(2,3).__array_interface__ Out[554]: {'data': (182286992, False), 'descr': [('', '<i4')], 'shape': (2, 3), 'strides': None, 'typestr': '<i4', 'version': 3} In [555]: x.ravel(order='F').reshape(2,3).__array_interface__ Out[555]: {'data': (182286992, False), 'descr': [('', '<i4')], 'shape': (2, 3), 'strides': None, 'typestr': '<i4', 'version': 3} 

I think there is an implicit "ravel" in the change:

 In [558]: xTreshape(2,3).__array_interface__ Out[558]: {'data': (182286992, False), 'descr': [('', '<i4')], 'shape': (2, 3), 'strides': None, 'typestr': '<i4', 'version': 3} 

(I have to redo these examples to get rid of ambiguity re-use of memory.) In any case, after reformatting the transposition requires the same dump that ravel with the change order. And as far as I can tell, only one copy is required for one of them. Other operations include changing attributes, such as form.

Maybe it's clearer if we just look at arrays

 In [565]: xT Out[565]: array([[0, 3], [1, 4], [2, 5]]) 

In T , we can still go through the array in numerical order. But after the change, 1 not located somewhere close to 0 . Obviously there was a copy.

 In [566]: xTreshape(2,3) Out[566]: array([[0, 3, 1], [4, 2, 5]]) 

order values ​​after ravel looks similar, and more evident after the change.

 In [567]: x.ravel(order='F') Out[567]: array([0, 3, 1, 4, 2, 5]) In [568]: x.ravel(order='F').reshape(2,3) Out[568]: array([[0, 3, 1], [4, 2, 5]]) 
+3
source

All Articles