Get data sequentially from numpy array in Matlab ordering

后端 未结 2 418
忘了有多久
忘了有多久 2021-01-20 02:46

As an example, suppose, in Matlab, a Matrix a(2,3,2) like this:

a(:,:,1) =

     1     2     3
     4     5     6


a(:,:,2) =

     7     8             


        
2条回答
  •  广开言路
    2021-01-20 03:40

    This is intended as a suplement to @Divakar's answer.

    In Octave I made x and a and saved them to a file

    >> x=[1, 4, 2, 5, 3, 6, 7, 10, 8, 11, 9, 12]
    >> a=reshape(x,2,3,2)
    
    a =
    
    ans(:,:,1) =
    
       1   2   3
       4   5   6
    
    ans(:,:,2) =
    
        7    8    9
       10   11   12
    

    I can flatten a with (same as your mex):

    >> a(:).'
    

    In numpy, with loadmat from scipy.io

    In [564]: data = loadmat('test.mat')
    In [566]: data['x']
    Out[566]: 
    array([[  1.,   4.,   2.,   5.,   3.,   6.,   7.,  10.,   8.,  11.,   9.,
             12.]])
    In [567]: data['a']
    Out[567]: 
    array([[[  1.,   7.],
            [  2.,   8.],
            [  3.,   9.]],
    
           [[  4.,  10.],
            [  5.,  11.],
            [  6.,  12.]]])
    

    ravel with order 'F' displays the original flat x:

    In [571]: data['a'].ravel(order='F')
    Out[571]: 
    array([  1.,   4.,   2.,   5.,   3.,   6.,   7.,  10.,   8.,  11.,   9., 12.])
    

    To help keep track of shapes I prefer to make them all different. For example

    >> x=0:23;
    >> a=reshape(x,2,3,4);
    

    and a displays as

    ans(:,:,1) =
    
       0   2   4
       1   3   5
    ...
    ans(:,:,4) =
    
       18   20   22
       19   21   23
    

    It is showing 4 (2,3) matrices.

    On the numpy side I get:

    In [575]: data['a'].shape
    Out[575]: (2, 3, 4)
    In [577]: data['a']
    Out[577]: 
    array([[[  0.,   6.,  12.,  18.],
            [  2.,   8.,  14.,  20.],
            [  4.,  10.,  16.,  22.]],
    
           [[  1.,   7.,  13.,  19.],
            [  3.,   9.,  15.,  21.],
            [  5.,  11.,  17.,  23.]]])
    

    This is 2 blocks of (3,4) shape.

    In [579]: data['a'].ravel('F')
    Out[579]: 
    array([  0.,   1.,   2.,   3.,   4.,   5.,   ...,  23.])
    

    I see two key differences between numpy and MATLAB/Octave. Default order is different, but numpy lets you specify F. And display of 3d (and larger) arrays is different. There's in effect a different notion of 'planes' or blocks.

    np.transpose changes the shape, strides, and order of an array, while keeping the same data base.

    Applied to a, it produces a (4,3,2) array with order 'C':

    In [580]: data['a'].T
    Out[580]: 
    array([[[  0.,   1.],
            [  2.,   3.],
            [  4.,   5.]],
    
     ....
           [[ 18.,  19.],
            [ 20.,  21.],
            [ 22.,  23.]]])
    In [581]: data['a'].T.ravel()
    Out[581]: 
    array([  0.,   1.,   2.,   3., ...22.,  23.])
    

    The MATLAB display can be replicated with:

    In [584]: for i in range(4):
         ...:     print(data['a'][:,:,i])
         ...:     
    [[ 0.  2.  4.]
     [ 1.  3.  5.]]
    [[  6.   8.  10.]
     [  7.   9.  11.]]
    [[ 12.  14.  16.]
     [ 13.  15.  17.]]
    [[ 18.  20.  22.]
     [ 19.  21.  23.]]
    

提交回复
热议问题